-
-
Notifications
You must be signed in to change notification settings - Fork 230
Expand file tree
/
Copy pathProgram.cs
More file actions
161 lines (132 loc) · 6.33 KB
/
Program.cs
File metadata and controls
161 lines (132 loc) · 6.33 KB
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/*
* This sample demonstrates the following basic features of Sentry, via a .NET console application:
* - Error Monitoring (both handled and unhandled exceptions)
* - Performance Tracing (Transactions / Spans)
* - Release Health (Sessions)
* - Logs
* - Metrics
* - MSBuild integration for Source Context (see the csproj)
*
* For more advanced features of the SDK, see Sentry.Samples.Console.Customized.
*/
using System.Diagnostics;
using System.Net;
using System.Net.Http;
using static System.Console;
// Initialize the Sentry SDK. (It is not necessary to dispose it.)
SentrySdk.Init(options =>
{
#if !SENTRY_DSN_DEFINED_IN_ENV
// A DSN is required. You can set here in code, or you can set it in the SENTRY_DSN environment variable.
// See https://docs.sentry.io/product/sentry-basics/dsn-explainer/
options.Dsn = SamplesShared.Dsn;
#endif
// When debug is enabled, the Sentry client will emit detailed debugging information to the console.
// This might be helpful, or might interfere with the normal operation of your application.
// We enable it here for demonstration purposes.
// You should not do this in your applications unless you are troubleshooting issues with Sentry.
options.Debug = true;
// This option is recommended, which enables Sentry's "Release Health" feature.
options.AutoSessionTracking = true;
// This option is recommended for client applications only. It ensures all threads use the same global scope.
// If you are writing a background service of any kind, you should remove this.
options.IsGlobalModeEnabled = true;
// This option tells Sentry to capture 100% of traces. You still need to start transactions and spans.
options.TracesSampleRate = 1.0;
// This option enables Sentry Logs created via SentrySdk.Logger.
options.EnableLogs = true;
options.SetBeforeSendLog(static log =>
{
// A demonstration of how you can drop logs based on some attribute they have
if (log.TryGetAttribute("suppress", out var attribute) && attribute is true)
{
return null;
}
// Drop logs with level Info
return log.Level is SentryLogLevel.Info ? null : log;
});
// Sentry (trace-connected) Metrics via SentrySdk.Experimental.Metrics are enabled by default.
options.Experimental.SetBeforeSendMetric(static metric =>
{
if (metric.TryGetValue(out int integer) && integer < 0)
{
// Return null to drop the metric
return null;
}
// A demonstration of how you can modify the metric object before sending it to Sentry
if (metric.Type is SentryMetricType.Counter)
{
metric.SetAttribute("operating_system.platform", Environment.OSVersion.Platform.ToString());
metric.SetAttribute("operating_system.version", Environment.OSVersion.Version.ToString());
}
return metric;
});
});
// This starts a new transaction and attaches it to the scope.
var transaction = SentrySdk.StartTransaction("Program Main", "function");
SentrySdk.ConfigureScope(scope => scope.Transaction = transaction);
// Do some work. (This is where you'd have your own application logic.)
await FirstFunction();
await SecondFunction();
await ThirdFunction();
// Always try to finish the transaction successfully.
// Unhandled exceptions will fail the transaction automatically.
// Optionally, you can try/catch the exception and call transaction.Finish(exception) on failure.
transaction.Finish();
async Task FirstFunction()
{
// This is an example of making an HttpRequest. A trace us automatically captured by Sentry for this.
var messageHandler = new SentryHttpMessageHandler();
var httpClient = new HttpClient(messageHandler, true);
var stopwatch = Stopwatch.StartNew();
var html = await httpClient.GetStringAsync("https://example.com/");
stopwatch.Stop();
WriteLine(html);
// Info-Log filtered via "BeforeSendLog" callback
SentrySdk.Logger.LogInfo("HTTP Request completed.");
// Counter-Metric prevented from being sent to Sentry via "BeforeSendMetric" callback
SentrySdk.Experimental.Metrics.EmitCounter("sentry.samples.console.basic.ignore", -1);
// Counter-Metric modified before sending it to Sentry via "BeforeSendMetric" callback
SentrySdk.Experimental.Metrics.EmitCounter("sentry.samples.console.basic.http_requests_completed", 1);
// Distribution-Metric sent as is (see "BeforeSendMetric" callback)
SentrySdk.Experimental.Metrics.EmitDistribution("sentry.samples.console.basic.http_request_duration", stopwatch.Elapsed.TotalSeconds, MeasurementUnit.Duration.Second,
[new KeyValuePair<string, object>("http.request.method", HttpMethod.Get.Method), new KeyValuePair<string, object>("http.response.status_code", (int)HttpStatusCode.OK)]);
}
async Task SecondFunction()
{
var span = transaction.StartChild("function", nameof(SecondFunction));
try
{
// Simulate doing some work
await Task.Delay(100);
// Throw an exception
throw new ApplicationException("Something happened!");
}
catch (Exception exception)
{
// This is an example of capturing a handled exception.
SentrySdk.CaptureException(exception);
// This is an example of capturing a structured log.
SentrySdk.Logger.LogError(static log => log.SetAttribute("method", nameof(SecondFunction)),
"Error with message: {0}", exception.Message);
span.Finish(exception);
}
finally
{
span.Finish();
}
}
async Task ThirdFunction()
{
// The `using` here ensures the span gets finished when we leave this method... This is unnecessary here,
// since the method always throws and the span will be finished automatically when the exception is captured,
// but this gives you another way to ensure spans are finished.
using var span = transaction.StartChild("function", nameof(ThirdFunction));
// Simulate doing some work
await Task.Delay(100);
// This is an example of a structured log that is filtered via the 'SetBeforeSendLog' delegate above.
SentrySdk.Logger.LogFatal(static log => log.SetAttribute("suppress", true),
"Crash imminent!");
// This is an example of an unhandled exception. It will be captured automatically.
throw new InvalidOperationException("Something happened that crashed the app!");
}