/
log.go
131 lines (125 loc) · 7.29 KB
/
log.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2016 Datadog, Inc.
package tracer
import (
"bytes"
"encoding/json"
"fmt"
"math"
"net/http"
"runtime"
"time"
"gopkg.in/DataDog/dd-trace-go.v1/internal/appsec"
"gopkg.in/DataDog/dd-trace-go.v1/internal/globalconfig"
"gopkg.in/DataDog/dd-trace-go.v1/internal/log"
"gopkg.in/DataDog/dd-trace-go.v1/internal/osinfo"
"gopkg.in/DataDog/dd-trace-go.v1/internal/version"
)
// startupInfo contains various information about the status of the tracer on startup.
type startupInfo struct {
Date string `json:"date"` // ISO 8601 date and time of start
OSName string `json:"os_name"` // Windows, Darwin, Debian, etc.
OSVersion string `json:"os_version"` // Version of the OS
Version string `json:"version"` // Tracer version
Lang string `json:"lang"` // "Go"
LangVersion string `json:"lang_version"` // Go version, e.g. go1.13
Env string `json:"env"` // Tracer env
Service string `json:"service"` // Tracer Service
AgentURL string `json:"agent_url"` // The address of the agent
AgentError string `json:"agent_error"` // Any error that occurred trying to connect to agent
Debug bool `json:"debug"` // Whether debug mode is enabled
AnalyticsEnabled bool `json:"analytics_enabled"` // True if there is a global analytics rate set
SampleRate string `json:"sample_rate"` // The default sampling rate for the rules sampler
SampleRateLimit string `json:"sample_rate_limit"` // The rate limit configured with the rules sampler
SamplingRules []SamplingRule `json:"sampling_rules"` // Rules used by the rules sampler
SamplingRulesError string `json:"sampling_rules_error"` // Any errors that occurred while parsing sampling rules
ServiceMappings map[string]string `json:"service_mappings"` // Service Mappings
Tags map[string]string `json:"tags"` // Global tags
RuntimeMetricsEnabled bool `json:"runtime_metrics_enabled"` // Whether runtime metrics are enabled
HealthMetricsEnabled bool `json:"health_metrics_enabled"` // Whether health metrics are enabled
ProfilerCodeHotspotsEnabled bool `json:"profiler_code_hotspots_enabled"` // Whether profiler code hotspots are enabled
ProfilerEndpointsEnabled bool `json:"profiler_endpoints_enabled"` // Whether profiler endpoints are enabled
ApplicationVersion string `json:"dd_version"` // Version of the user's application
Architecture string `json:"architecture"` // Architecture of host machine
GlobalService string `json:"global_service"` // Global service string. If not-nil should be same as Service. (#614)
LambdaMode string `json:"lambda_mode"` // Whether the client has enabled lambda mode
AppSec bool `json:"appsec"` // AppSec status: true when started, false otherwise.
AgentFeatures agentFeatures `json:"agent_features"` // Lists the capabilities of the agent.
PartialFlushEnabled bool `json:"partial_flush_enabled"` // Whether Partial Flushing is enabled
PartialFlushMinSpans int `json:"partial_flush_min_spans"` // The min number of spans to trigger a partial flush
}
// checkEndpoint tries to connect to the URL specified by endpoint.
// If the endpoint is not reachable, checkEndpoint returns an error
// explaining why.
func checkEndpoint(c *http.Client, endpoint string) error {
req, err := http.NewRequest("POST", endpoint, bytes.NewReader([]byte{0x90}))
if err != nil {
return fmt.Errorf("cannot create http request: %v", err)
}
req.Header.Set(traceCountHeader, "0")
req.Header.Set("Content-Type", "application/msgpack")
res, err := c.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
return nil
}
// logStartup generates a startupInfo for a tracer and writes it to the log in
// JSON format.
func logStartup(t *tracer) {
tags := make(map[string]string)
for k, v := range t.config.globalTags {
tags[k] = fmt.Sprintf("%v", v)
}
info := startupInfo{
Date: time.Now().Format(time.RFC3339),
OSName: osinfo.OSName(),
OSVersion: osinfo.OSVersion(),
Version: version.Tag,
Lang: "Go",
LangVersion: runtime.Version(),
Env: t.config.env,
Service: t.config.serviceName,
AgentURL: t.config.transport.endpoint(),
Debug: t.config.debug,
AnalyticsEnabled: !math.IsNaN(globalconfig.AnalyticsRate()),
SampleRate: fmt.Sprintf("%f", t.rulesSampling.traces.globalRate),
SampleRateLimit: "disabled",
SamplingRules: append(t.config.traceRules, t.config.spanRules...),
ServiceMappings: t.config.serviceMappings,
Tags: tags,
RuntimeMetricsEnabled: t.config.runtimeMetrics,
HealthMetricsEnabled: t.config.runtimeMetrics,
ApplicationVersion: t.config.version,
ProfilerCodeHotspotsEnabled: t.config.profilerHotspots,
ProfilerEndpointsEnabled: t.config.profilerEndpoints,
Architecture: runtime.GOARCH,
GlobalService: globalconfig.ServiceName(),
LambdaMode: fmt.Sprintf("%t", t.config.logToStdout),
AgentFeatures: t.config.agent,
AppSec: appsec.Enabled(),
PartialFlushEnabled: t.config.partialFlushEnabled,
PartialFlushMinSpans: t.config.partialFlushMinSpans,
}
if _, _, err := samplingRulesFromEnv(); err != nil {
info.SamplingRulesError = fmt.Sprintf("%s", err)
}
if limit, ok := t.rulesSampling.TraceRateLimit(); ok {
info.SampleRateLimit = fmt.Sprintf("%v", limit)
}
if !t.config.logToStdout {
if err := checkEndpoint(t.config.httpClient, t.config.transport.endpoint()); err != nil {
info.AgentError = fmt.Sprintf("%s", err)
log.Warn("DIAGNOSTICS Unable to reach agent intake: %s", err)
}
}
bs, err := json.Marshal(info)
if err != nil {
log.Warn("DIAGNOSTICS Failed to serialize json for startup log (%v) %#v\n", err, info)
return
}
log.Info("DATADOG TRACER CONFIGURATION %s\n", string(bs))
}