Skip to content

Commit d418f5a

Browse files
author
Bastian Krol
committed
feat: improve robustness of custom service naming
Use INSTANA_SERVICE_NAME value for span.data.service annotation. Previously, span.data.service has only been added when configured via in-code configuration, but not when the environment variable INSTANA_SERVICE_NAME is set. The Go tracer implicitly relied on the back end to link spans to infrastructure entities and get the service name from there. Adding the annotation to the span makes service name extraction more resilient, in particular with respect to situations in which spans cannot be linked to infrastructure. The binary name is now kept as a separate attribute in the sensor struct. This is to keep the pre-existing behavior to fall back to the binary's name when sending the infrastructure snapshot `name` attribute and the `service` attribute for events. However, we explicitly do not want to add the binary's name as an annotation to all spans.
1 parent 25c77a3 commit d418f5a

File tree

4 files changed

+72
-7
lines changed

4 files changed

+72
-7
lines changed

event.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ const (
3939
func SendDefaultServiceEvent(title string, text string, sev severity, duration time.Duration) {
4040
var service string
4141
if sensor != nil {
42-
service = sensor.serviceName
42+
service = sensor.serviceOrBinaryName()
4343
}
4444

4545
// If the sensor is not yet initialized, there is no default service (as

json_span_test.go

+56
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package instana_test
55

66
import (
7+
"os"
78
"testing"
89

910
instana "github.com/instana/go-sensor"
@@ -43,6 +44,61 @@ func TestSpanKind_String(t *testing.T) {
4344
}
4445
}
4546

47+
func TestServiceNameViaConfig(t *testing.T) {
48+
recorder := instana.NewTestRecorder()
49+
tracer := instana.NewTracerWithEverything(
50+
&instana.Options{
51+
AgentClient: alwaysReadyClient{},
52+
Service: "Service Name",
53+
},
54+
recorder,
55+
)
56+
defer instana.ShutdownSensor()
57+
sp := tracer.StartSpan("g.http")
58+
sp.Finish()
59+
spans := recorder.GetQueuedSpans()
60+
61+
require.Len(t, spans, 1)
62+
span := spans[0]
63+
assert.Equal(t, "Service Name", span.Data.(instana.HTTPSpanData).SpanData.Service)
64+
assert.Contains(t, spanToJson(t, span), "\"service\":\"Service Name\"")
65+
}
66+
67+
func TestServiceNameViaEnvVar(t *testing.T) {
68+
envVarOriginalValue, wasSet := os.LookupEnv("INSTANA_SERVICE_NAME")
69+
os.Setenv("INSTANA_SERVICE_NAME", "Service Name")
70+
defer func() {
71+
if wasSet {
72+
os.Setenv("INSTANA_SERVICE_NAME", envVarOriginalValue)
73+
} else {
74+
os.Unsetenv("INSTANA_SERVICE_NAME")
75+
}
76+
}()
77+
78+
recorder := instana.NewTestRecorder()
79+
tracer := instana.NewTracerWithEverything(
80+
&instana.Options{
81+
AgentClient: alwaysReadyClient{},
82+
},
83+
recorder,
84+
)
85+
defer instana.ShutdownSensor()
86+
sp := tracer.StartSpan("g.http")
87+
sp.Finish()
88+
spans := recorder.GetQueuedSpans()
89+
90+
require.Len(t, spans, 1)
91+
span := spans[0]
92+
assert.Equal(t, "Service Name", span.Data.(instana.HTTPSpanData).SpanData.Service)
93+
assert.Contains(t, spanToJson(t, span), "\"service\":\"Service Name\"")
94+
}
95+
96+
func spanToJson(t *testing.T, span instana.Span) string {
97+
jsonBytes, err := span.MarshalJSON()
98+
assert.NoError(t, err)
99+
return string(jsonBytes[:])
100+
}
101+
46102
func TestNewSDKSpanData(t *testing.T) {
47103
recorder := instana.NewTestRecorder()
48104
tracer := instana.NewTracerWithEverything(&instana.Options{AgentClient: alwaysReadyClient{}}, recorder)

sensor.go

+14-5
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ type sensorS struct {
5252
logger LeveledLogger
5353
options *Options
5454
serviceName string
55+
binaryName string
5556

5657
mu sync.RWMutex
5758
agent AgentClient
@@ -70,9 +71,7 @@ func newSensor(options *Options) *sensorS {
7071
s := &sensorS{
7172
options: options,
7273
serviceName: options.Service,
73-
}
74-
if s.serviceName == "" {
75-
s.serviceName = binaryName
74+
binaryName: binaryName,
7675
}
7776

7877
s.setLogger(defaultLogger)
@@ -117,11 +116,11 @@ func newSensor(options *Options) *sensorS {
117116
}
118117
}
119118

120-
agent = newServerlessAgent(s.serviceName, agentEndpoint, os.Getenv("INSTANA_AGENT_KEY"), client, s.logger)
119+
agent = newServerlessAgent(s.serviceOrBinaryName(), agentEndpoint, os.Getenv("INSTANA_AGENT_KEY"), client, s.logger)
121120
}
122121

123122
if agent == nil {
124-
agent = newAgent(s.serviceName, s.options.AgentHost, s.options.AgentPort, s.logger)
123+
agent = newAgent(s.serviceOrBinaryName(), s.options.AgentHost, s.options.AgentPort, s.logger)
125124
}
126125

127126
s.setAgent(agent)
@@ -162,6 +161,16 @@ func (r *sensorS) Agent() AgentClient {
162161
return r.agent
163162
}
164163

164+
func (r *sensorS) serviceOrBinaryName() string {
165+
if r == nil {
166+
return ""
167+
}
168+
if r.serviceName != "" {
169+
return r.serviceName
170+
}
171+
return r.binaryName
172+
}
173+
165174
// InitSensor intializes the sensor (without tracing) to begin collecting
166175
// and reporting metrics.
167176
func InitSensor(options *Options) {

tracer.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ func (r *tracerS) StartSpanWithOptions(operationName string, opts ot.StartSpanOp
112112
return &spanS{
113113
context: sc,
114114
tracer: r,
115-
Service: sensor.options.Service,
115+
Service: sensor.serviceName,
116116
Operation: operationName,
117117
Start: startTime,
118118
Duration: -1,

0 commit comments

Comments
 (0)