@@ -12,6 +12,64 @@ module OpenTelemetry
1212 module Instrumentation
1313 module PG
1414 module Patches
15+ module ConnectionHelper
16+ module_function
17+
18+ def set_connection_attributes ( span , conn , config )
19+ attributes = {
20+ 'db.system' => 'postgresql' ,
21+ 'db.name' => conn . db ,
22+ 'db.user' => conn . user
23+ }
24+ attributes [ 'peer.service' ] = config [ :peer_service ] if config [ :peer_service ]
25+
26+ h = conn . host
27+ if h &.start_with? ( '/' )
28+ attributes [ 'net.sock.family' ] = 'unix'
29+ attributes [ 'net.peer.name' ] = h
30+ else
31+ attributes [ 'net.transport' ] = 'ip_tcp'
32+ attributes [ 'net.peer.name' ] = h
33+ attributes [ 'net.peer.port' ] = conn . port if defined? ( ::PG ::DEF_PGPORT )
34+ end
35+
36+ attributes . merge! ( OpenTelemetry ::Instrumentation ::PG . attributes )
37+ attributes . compact!
38+
39+ span . add_attributes ( attributes )
40+ end
41+ end
42+
43+ # Module to prepend to PG::Connection singleton class for connection initialization
44+ # We override `new` instead of `initialize` because PG::Connection.new is implemented
45+ # as a Ruby method that calls the C-level connect_start, bypassing initialize.
46+ # We also need to override the aliases (open, connect, async_connect) because they
47+ # were aliased before our prepend, so they point to the original method.
48+ # See: https://github.com/ged/ruby-pg/blob/master/lib/pg/connection.rb#L870
49+ module ClassMethods
50+ def new ( ...)
51+ tracer = OpenTelemetry ::Instrumentation ::PG ::Instrumentation . instance . tracer
52+ config = OpenTelemetry ::Instrumentation ::PG ::Instrumentation . instance . config
53+
54+ tracer . in_span ( 'connect' , kind : :client ) do |span |
55+ if block_given?
56+ super do |conn |
57+ ConnectionHelper . set_connection_attributes ( span , conn , config )
58+ yield conn
59+ end
60+ else
61+ conn = super
62+ ConnectionHelper . set_connection_attributes ( span , conn , config )
63+ conn
64+ end
65+ end
66+ end
67+
68+ PG ::Constants ::CONNECTION_METHODS . each do |method |
69+ alias_method method , :new
70+ end
71+ end
72+
1573 # Module to prepend to PG::Connection for instrumentation
1674 module Connection # rubocop:disable Metrics/ModuleLength
1775 # Capture the first word (including letters, digits, underscores, & '.', ) that follows common table commands
0 commit comments