# encoding: utf-8 module OneApm module Agent module Instrumentation module ActiveRecordHelper module_function DATABASE = "Database".freeze STATEMENT = "statement".freeze ALL = "Database/all".freeze ALLWEB = "Database/allWeb".freeze ALLOTHER = "Database/allOther".freeze def operation_metric_for(product, operation, model_name) met_info = [ DATABASE, STATEMENT] met_info << product met_info << model_name met_info << operation met_info.compact.join("/") end def operation_all_metric_for(product, operation) met_info = [ DATABASE, STATEMENT] #without data_base_name met_info << without_database_name(product) met_info << operation met_info.compact.join("/") end def product_rollup(product) "Database/#{STATEMENT}/#{without_database_name(product)}/all" end def rollup_metrics_for return ALLWEB if OneApm::Transaction.recording_web_transaction? return ALLOTHER end #Database/statement/SqlType:10.128.6.33:3306/all def all(product) met_info = [ DATABASE, STATEMENT] met_info << database_type(product) met_info.compact.join("/") end def metric_for(product, operation, model_name = nil) metrics = [ operation_metric_for(product, operation, model_name), operation_all_metric_for(product, operation), product_rollup(product), rollup_metrics_for, all(product) ] metrics end def model_for_name(name) return 'SQL' unless name && name.respond_to?(:split) parts = name.split(' ') if parts.size == 2 parts.first else 'SQL' end end def operator_for_name(name) return unless name && name.include?(' ') parts = name.split(' ') return rename_for(parts.last.downcase) if parts.size == 2 end def rename_for operation op_name = case operation.to_s when 'find', 'load', 'count', 'exists', 'all', 'get', 'select' 'select' when 'destroy', 'delete' 'delete' when 'create', 'insert' 'insert' when 'update', 'save' 'update' when 'other' 'other' else nil end op_name end def operator_for_sql(sql) txn = OneApm::Transaction.tl_current metric = txn && txn.database_metric_name operation = "" if metric.nil? operation = OneApm::Agent::Database.parse_operation_from_query(sql) end operation || "other" end def database_info config = {} info = [] db_type, default_port = type_and_default_port_for_db config.fetch(:adapter, "SQL") info << db_type info << config.fetch(:host, '127.0.0.1') info << config.fetch(:port, default_port) #database need join with '/' "#{info.compact.uniq.join(":")}/#{config.fetch(:database, 'unknown')}" end def without_database_name(product) product.split('/')[0..-2].join('/') end def database_type(product) product.split(':')[0] end def type_and_default_port_for_db adapter type, port = case adapter when /mysql/ then [:MySQL, 3306] when /postgresql/ then [:PostgreSQL, 5432] when /oracle/ then [:Oracle, 1521] when /sqlserver/ then [:SQLSever, 1433] else [:Other, -1] end end end end end end