Skip to content

Commit ea079b0

Browse files
addressed concerns discussed during brownbag session (#425)
* addressed concerns discussed during brownbag session * updated fields in aitelemetry * addressed review comments * flipped the metadata thread field * fixed compilation errors * added default refresh timeout * moved out of for loop * added unittest * added disableall field which disables everything(trace,metric) * removed disable logic from ai package * added an error check for getting metadata
1 parent 84fb35b commit ea079b0

File tree

3 files changed

+122
-43
lines changed

3 files changed

+122
-43
lines changed

aitelemetry/api.go

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,27 @@ type Metric struct {
2121
CustomDimensions map[string]string
2222
}
2323

24+
type AIConfig struct {
25+
AppName string
26+
AppVersion string
27+
BatchSize int
28+
BatchInterval int
29+
DisableMetadataRefreshThread bool
30+
RefreshTimeout int
31+
DebugMode bool
32+
}
33+
2434
// TelmetryHandle holds appinsight handles and metadata
2535
type telemetryHandle struct {
26-
telemetryConfig *appinsights.TelemetryConfiguration
27-
appName string
28-
appVersion string
29-
metadata common.Metadata
30-
diagListener appinsights.DiagnosticsMessageListener
31-
client appinsights.TelemetryClient
32-
enableMetadataRefreshThread bool
33-
refreshTimeout int
34-
rwmutex sync.RWMutex
36+
telemetryConfig *appinsights.TelemetryConfiguration
37+
appName string
38+
appVersion string
39+
metadata common.Metadata
40+
diagListener appinsights.DiagnosticsMessageListener
41+
client appinsights.TelemetryClient
42+
disableMetadataRefreshThread bool
43+
refreshTimeout int
44+
rwmutex sync.RWMutex
3545
}
3646

3747
// Telemetry Interface to send metrics/Logs to appinsights

aitelemetry/telemetrywrapper.go

Lines changed: 50 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -15,33 +15,55 @@ const (
1515
vmSizeStr = "VMSize"
1616
osVersionStr = "OSVersion"
1717
locationStr = "Region"
18-
appVersionStr = "Appversion"
18+
appNameStr = "AppName"
1919
subscriptionIDStr = "SubscriptionID"
20+
vmNameStr = "VMName"
2021
defaultTimeout = 10
2122
)
2223

24+
var debugMode bool
25+
2326
func messageListener() appinsights.DiagnosticsMessageListener {
24-
return appinsights.NewDiagnosticsMessageListener(func(msg string) error {
25-
log.Printf("[AppInsights] [%s] %s\n", time.Now().Format(time.UnixDate), msg)
26-
return nil
27-
})
27+
if debugMode {
28+
return appinsights.NewDiagnosticsMessageListener(func(msg string) error {
29+
debuglog("[AppInsights] [%s] %s\n", time.Now().Format(time.UnixDate), msg)
30+
return nil
31+
})
32+
}
33+
34+
return nil
35+
}
36+
37+
func debuglog(format string, args ...interface{}) {
38+
if debugMode {
39+
log.Printf(format, args...)
40+
}
2841
}
2942

3043
func getMetadata(th *telemetryHandle) {
3144
var metadata common.Metadata
3245
var err error
3346

47+
if th.refreshTimeout < 4 {
48+
th.refreshTimeout = defaultTimeout
49+
}
50+
3451
// check if metadata in memory otherwise initiate wireserver request
3552
for {
3653
metadata, err = common.GetHostMetadata(metadataFile)
37-
if err == nil || !th.enableMetadataRefreshThread {
54+
if err == nil || th.disableMetadataRefreshThread {
3855
break
3956
}
4057

41-
log.Printf("[AppInsights] Error getting metadata %v. Sleep for %d", err, th.refreshTimeout)
58+
debuglog("[AppInsights] Error getting metadata %v. Sleep for %d", err, th.refreshTimeout)
4259
time.Sleep(time.Duration(th.refreshTimeout) * time.Second)
4360
}
4461

62+
if err != nil {
63+
debuglog("[AppInsights] Error getting metadata %v", err)
64+
return
65+
}
66+
4567
//acquire write lock before writing metadata to telemetry handle
4668
th.rwmutex.Lock()
4769
th.metadata = metadata
@@ -50,46 +72,42 @@ func getMetadata(th *telemetryHandle) {
5072
// Save metadata retrieved from wireserver to a file
5173
kvs, err := store.NewJsonFileStore(metadataFile)
5274
if err != nil {
53-
log.Printf("[AppInsights] Error initializing kvs store: %v", err)
75+
debuglog("[AppInsights] Error initializing kvs store: %v", err)
5476
return
5577
}
5678

5779
kvs.Lock(true)
5880
err = common.SaveHostMetadata(th.metadata, metadataFile)
5981
kvs.Unlock(true)
6082
if err != nil {
61-
log.Printf("[AppInsights] saving host metadata failed with :%v", err)
83+
debuglog("[AppInsights] saving host metadata failed with :%v", err)
6284
}
6385
}
6486

65-
// NewAITelemetry creates telemetry handle with user specified appinsights key.
87+
// NewAITelemetry creates telemetry handle with user specified appinsights id.
6688
func NewAITelemetry(
67-
key string,
68-
appName string,
69-
appVersion string,
70-
batchSize int,
71-
batchInterval int,
72-
enableMetadataRefreshThread bool,
73-
refreshTimeout int,
89+
id string,
90+
aiConfig AIConfig,
7491
) TelemetryHandle {
7592

76-
telemetryConfig := appinsights.NewTelemetryConfiguration(key)
77-
telemetryConfig.MaxBatchSize = batchSize
78-
telemetryConfig.MaxBatchInterval = time.Duration(batchInterval) * time.Second
93+
telemetryConfig := appinsights.NewTelemetryConfiguration(id)
94+
telemetryConfig.MaxBatchSize = aiConfig.BatchSize
95+
telemetryConfig.MaxBatchInterval = time.Duration(aiConfig.BatchInterval) * time.Second
96+
debugMode = aiConfig.DebugMode
7997

8098
th := &telemetryHandle{
81-
client: appinsights.NewTelemetryClientFromConfig(telemetryConfig),
82-
appName: appName,
83-
appVersion: appVersion,
84-
diagListener: messageListener(),
85-
enableMetadataRefreshThread: enableMetadataRefreshThread,
86-
refreshTimeout: refreshTimeout,
99+
client: appinsights.NewTelemetryClientFromConfig(telemetryConfig),
100+
appName: aiConfig.AppName,
101+
appVersion: aiConfig.AppVersion,
102+
diagListener: messageListener(),
103+
disableMetadataRefreshThread: aiConfig.DisableMetadataRefreshThread,
104+
refreshTimeout: aiConfig.RefreshTimeout,
87105
}
88106

89-
if th.enableMetadataRefreshThread {
90-
go getMetadata(th)
91-
} else {
107+
if th.disableMetadataRefreshThread {
92108
getMetadata(th)
109+
} else {
110+
go getMetadata(th)
93111
}
94112

95113
return th
@@ -104,14 +122,14 @@ func (th *telemetryHandle) TrackLog(report Report) {
104122
//Override few of existing columns with metadata
105123
trace.Tags.User().SetAuthUserId(runtime.GOOS)
106124
trace.Tags.Operation().SetId(report.Context)
107-
trace.Tags.Operation().SetParentId(th.appName)
125+
trace.Tags.Operation().SetParentId(th.appVersion)
108126

109127
// copy app specified custom dimension
110128
for key, value := range report.CustomDimensions {
111129
trace.Properties[key] = value
112130
}
113131

114-
trace.Properties[appVersionStr] = th.appVersion
132+
trace.Properties[appNameStr] = th.appName
115133

116134
// Acquire read lock to read metadata
117135
th.rwmutex.RLock()
@@ -148,6 +166,7 @@ func (th *telemetryHandle) TrackMetric(metric Metric) {
148166
if metadata.SubscriptionID != "" {
149167
aimetric.Properties[locationStr] = th.metadata.Location
150168
aimetric.Properties[subscriptionIDStr] = th.metadata.SubscriptionID
169+
aimetric.Properties[vmNameStr] = th.metadata.VMName
151170
}
152171

153172
// copy custom dimensions

aitelemetry/telemetrywrapper_test.go

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package aitelemetry
22

33
import (
4+
"fmt"
45
"os"
6+
"path/filepath"
57
"runtime"
68
"testing"
79

@@ -15,22 +17,52 @@ func TestMain(m *testing.M) {
1517
if runtime.GOOS == "linux" {
1618
platform.ExecuteCommand("cp metadata_test.json /tmp/azuremetadata.json")
1719
} else {
18-
platform.ExecuteCommand("copy metadata_test.json azuremetadata.json")
20+
metadataFile := filepath.FromSlash(os.Getenv("TEMP")) + "\\azuremetadata.json"
21+
cmd := fmt.Sprintf("copy metadata_test.json %s", metadataFile)
22+
platform.ExecuteCommand(cmd)
1923
}
2024

2125
exitCode := m.Run()
2226

2327
if runtime.GOOS == "linux" {
2428
platform.ExecuteCommand("rm /tmp/azuremetadata.json")
2529
} else {
26-
platform.ExecuteCommand("del azuremetadata.json")
30+
metadataFile := filepath.FromSlash(os.Getenv("TEMP")) + "\\azuremetadata.json"
31+
cmd := fmt.Sprintf("del %s", metadataFile)
32+
platform.ExecuteCommand(cmd)
2733
}
2834

2935
os.Exit(exitCode)
3036
}
3137

38+
func TestEmptyAIKey(t *testing.T) {
39+
aiConfig := AIConfig{
40+
AppName: "testapp",
41+
AppVersion: "v1.0.26",
42+
BatchSize: 4096,
43+
BatchInterval: 2,
44+
RefreshTimeout: 10,
45+
DebugMode: true,
46+
DisableMetadataRefreshThread: true,
47+
}
48+
th := NewAITelemetry("", aiConfig)
49+
if th == nil {
50+
t.Errorf("Error intializing AI telemetry")
51+
}
52+
th.Close(10)
53+
}
54+
3255
func TestNewAITelemetry(t *testing.T) {
33-
th = NewAITelemetry("00ca2a73-c8d6-4929-a0c2-cf84545ec225", "testapp", "v1.0.26", 4096, 2, false, 10)
56+
aiConfig := AIConfig{
57+
AppName: "testapp",
58+
AppVersion: "v1.0.26",
59+
BatchSize: 4096,
60+
BatchInterval: 2,
61+
RefreshTimeout: 10,
62+
DebugMode: true,
63+
DisableMetadataRefreshThread: true,
64+
}
65+
th = NewAITelemetry("00ca2a73-c8d6-4929-a0c2-cf84545ec225", aiConfig)
3466
if th == nil {
3567
t.Errorf("Error intializing AI telemetry")
3668
}
@@ -61,3 +93,21 @@ func TestTrackLog(t *testing.T) {
6193
func TestClose(t *testing.T) {
6294
th.Close(10)
6395
}
96+
97+
func TestClosewithoutSend(t *testing.T) {
98+
aiConfig := AIConfig{
99+
AppName: "testapp",
100+
AppVersion: "v1.0.26",
101+
BatchSize: 4096,
102+
BatchInterval: 2,
103+
DisableMetadataRefreshThread: true,
104+
RefreshTimeout: 10,
105+
}
106+
107+
thtest := NewAITelemetry("00ca2a73-c8d6-4929-a0c2-cf84545ec225", aiConfig)
108+
if thtest == nil {
109+
t.Errorf("Error intializing AI telemetry")
110+
}
111+
112+
thtest.Close(10)
113+
}

0 commit comments

Comments
 (0)