-
Notifications
You must be signed in to change notification settings - Fork 65
App insights Telemetry for Commands #409
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
18d692d
b3ea0c0
1697b74
206e578
186253e
a8e925f
f7d5292
b9879f1
102b24a
ad3bf3f
42b9e4e
6fdb565
682ae27
be3f2ca
ed1470b
826d370
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
name: Download Info | ||
|
||
on: | ||
push: | ||
branches: | ||
- main | ||
|
||
jobs: | ||
print-download-info: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- name: Check out code | ||
uses: actions/checkout@v2 | ||
|
||
- name: Set up Python | ||
uses: actions/setup-python@v2 | ||
with: | ||
python-version: '3.x' # Replace with the desired Python version | ||
|
||
- name: Install dependencies | ||
run: | | ||
python -m pip install --upgrade pip | ||
pip install requests | ||
|
||
- name: Get Download Info | ||
run: | | ||
python - <<EOF | ||
import requests | ||
|
||
url = "https://github.com/api/repos/microsoft/go-sqlcmd/releases" | ||
response = requests.get(url) | ||
data = response.json() | ||
|
||
for release in data: | ||
for asset in release['assets']: | ||
browser_download_url = asset['browser_download_url'] | ||
download_count = asset['download_count'] | ||
print("Download URL:", browser_download_url) | ||
print("Download Count:", download_count) | ||
print() | ||
EOF |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package telemetry | ||
|
||
import ( | ||
"fmt" | ||
"time" | ||
|
||
"github.com/microsoft/ApplicationInsights-Go/appinsights" | ||
) | ||
|
||
var telemetryClient appinsights.TelemetryClient | ||
|
||
func SetTelemetryClient(client appinsights.TelemetryClient) { | ||
telemetryClient = client | ||
} | ||
|
||
func SetTelemetryClientFromInstrumentationKey(instrumentationKey string) { | ||
telemetryClient = appinsights.NewTelemetryClient(instrumentationKey) | ||
} | ||
|
||
type Telemetry struct { | ||
Client appinsights.TelemetryClient | ||
} | ||
|
||
func InitializeAppInsights() { | ||
instrumentationKey := "3fdeec77-2951-456f-bcb2-9f003b512a3f" | ||
config := appinsights.NewTelemetryConfiguration(instrumentationKey) | ||
telemetryClient = appinsights.NewTelemetryClientFromConfig(config) | ||
SetTelemetryClient(telemetryClient) | ||
// Add a diagnostics listener for printing telemetry messages | ||
appinsights.NewDiagnosticsMessageListener(func(msg string) error { | ||
fmt.Printf("[%s] %s\n", time.Now().Format(time.UnixDate), msg) | ||
return nil | ||
}) | ||
} | ||
|
||
// TrackCommand tracks a command execution event | ||
func TrackCommand(command string) { | ||
event := appinsights.NewEventTelemetry("command") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need a hierarchy/categorized name for events and properties so we can group things? Eg in SSMS there are multiple events that happen to an object explorer node. The event names are
There are also a bunch of "ambient" properties we tried to include in most events, like the type of server OE is connected to. In our case, I feel like Also - for "modern" commands we should log the context id (a guid) with every relevant event. That will enable us to track the lifecycle of a context. EG if the customer runs sqlcmd to create a context, there should be an event that logs the context id guid along with non-PII metadata about the context (container type, operating system of the host, version of SQL, etc). Subsequent commands using that context can then be correlated with that creation. If the user uses an existing context for an operation, we can log a 'ConnectContext' event that has the similar metadata as the |
||
event.Properties["command"] = command | ||
telemetryClient.Track(event) | ||
} | ||
|
||
// TrackSubCommand tracks a sub-command execution event | ||
func TrackSubCommand(command, subCommand string) { | ||
event := appinsights.NewEventTelemetry("sub-command") | ||
event.Properties["command"] = command | ||
event.Properties["sub-command"] = subCommand | ||
telemetryClient.Track(event) | ||
} | ||
|
||
func TrackEvent(eventName string, properties map[string]string) { | ||
event := appinsights.NewEventTelemetry(eventName) | ||
for key, value := range properties { | ||
event.Properties[key] = value | ||
} | ||
telemetryClient.Track(event) | ||
} | ||
|
||
func CloseTelemetry() { | ||
telemetryClient.Channel().Close() | ||
} | ||
func FlushTelemetry() { | ||
telemetryClient.Channel().Flush() | ||
} | ||
|
||
func LogMessage(msg string) error { | ||
fmt.Printf("[%s] %s\n", time.Now().Format(time.UnixDate), msg) | ||
return nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it could be useful to define a method that accepts event name and properties plus a func() as input. It would run the function with a timer and add an elapsed time property to the telemetry event before posting it.
Something like
then we can measure how long it takes to deploy things without trying to look for a "begin" event and its corresponding "end" event.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good suggestion , but i would like to add one POV here . Instead of every granular event to have start and end time , we should have these func parmater with specified events (such as deploy and create).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I don't think every operation needs an elapsed time property, just certain ones. At the lowest level, though, the function just needs to take an event name and properties. The application-level code will decide which events need to use it.