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