-
Notifications
You must be signed in to change notification settings - Fork 18
System.Diagnostics.ActivitySource support for observability #83
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: master
Are you sure you want to change the base?
Changes from 3 commits
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 |
---|---|---|
@@ -1,80 +1,78 @@ | ||
STORAGE: NONE | ||
RESTRICTION: || (== net8.0) (== netstandard2.0) (== netstandard2.1) | ||
RESTRICTION: || (== net9.0) (== netstandard2.0) (== netstandard2.1) | ||
NUGET | ||
remote: https://api.nuget.org/v3/index.json | ||
AWSSDK.Core (3.7.300.11) | ||
Microsoft.Bcl.AsyncInterfaces (>= 1.1) - restriction: || (&& (== net8.0) (< netcoreapp3.1)) (== netstandard2.0) (== netstandard2.1) | ||
AWSSDK.DynamoDBv2 (3.7.300.11) | ||
AWSSDK.Core (>= 3.7.300.11 < 4.0) | ||
DotNet.ReproducibleBuilds (1.1.1) - copy_local: true | ||
Microsoft.SourceLink.AzureRepos.Git (>= 1.1.1) | ||
Microsoft.SourceLink.Bitbucket.Git (>= 1.1.1) | ||
Microsoft.SourceLink.GitHub (>= 1.1.1) | ||
Microsoft.SourceLink.GitLab (>= 1.1.1) | ||
AWSSDK.Core (3.7.400.70) | ||
Microsoft.Bcl.AsyncInterfaces (>= 1.1) - restriction: || (&& (== net9.0) (< netcoreapp3.1)) (== netstandard2.0) (== netstandard2.1) | ||
AWSSDK.DynamoDBv2 (3.7.404.11) | ||
AWSSDK.Core (>= 3.7.400.70 < 4.0) | ||
DotNet.ReproducibleBuilds (1.2.25) - copy_local: true | ||
FSharp.Core (4.7.2) | ||
Microsoft.Bcl.AsyncInterfaces (8.0) - restriction: || (&& (== net8.0) (< netcoreapp3.1)) (== netstandard2.0) (== netstandard2.1) | ||
System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: || (&& (== net8.0) (>= net462)) (&& (== net8.0) (< netstandard2.1)) (== netstandard2.0) (&& (== netstandard2.1) (>= net462)) | ||
Microsoft.Build.Tasks.Git (8.0) - copy_local: true | ||
Microsoft.SourceLink.AzureRepos.Git (8.0) - copy_local: true | ||
Microsoft.Build.Tasks.Git (>= 8.0) | ||
Microsoft.SourceLink.Common (>= 8.0) | ||
Microsoft.SourceLink.Bitbucket.Git (8.0) - copy_local: true | ||
Microsoft.Build.Tasks.Git (>= 8.0) | ||
Microsoft.SourceLink.Common (>= 8.0) | ||
Microsoft.SourceLink.Common (8.0) - copy_local: true | ||
Microsoft.SourceLink.GitHub (8.0) - copy_local: true | ||
Microsoft.Build.Tasks.Git (>= 8.0) | ||
Microsoft.SourceLink.Common (>= 8.0) | ||
Microsoft.SourceLink.GitLab (8.0) - copy_local: true | ||
Microsoft.Build.Tasks.Git (>= 8.0) | ||
Microsoft.SourceLink.Common (>= 8.0) | ||
System.Runtime.CompilerServices.Unsafe (6.0) - restriction: || (&& (== net8.0) (>= net461)) (&& (== net8.0) (>= net462)) (&& (== net8.0) (< netcoreapp2.1) (< netstandard2.1)) (&& (== net8.0) (< netstandard1.0)) (&& (== net8.0) (< netstandard2.0)) (&& (== net8.0) (>= wp8)) (== netstandard2.0) (&& (== netstandard2.1) (>= net462)) | ||
System.Threading.Tasks.Extensions (4.5.4) - restriction: || (&& (== net8.0) (>= net462)) (&& (== net8.0) (< netstandard2.1)) (== netstandard2.0) (&& (== netstandard2.1) (>= net462)) | ||
System.Runtime.CompilerServices.Unsafe (>= 4.5.3) - restriction: || (&& (== net8.0) (>= net461)) (&& (== net8.0) (< netcoreapp2.1)) (&& (== net8.0) (< netstandard1.0)) (&& (== net8.0) (< netstandard2.0)) (&& (== net8.0) (>= wp8)) (== netstandard2.0) (== netstandard2.1) | ||
Microsoft.Bcl.AsyncInterfaces (9.0) - restriction: || (&& (== net9.0) (>= net462)) (&& (== net9.0) (< net8.0)) (== netstandard2.0) (== netstandard2.1) | ||
System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: || (&& (== net9.0) (>= net462)) (&& (== net9.0) (< netstandard2.1)) (== netstandard2.0) (&& (== netstandard2.1) (>= net462)) | ||
System.Buffers (4.6) - restriction: || (&& (== net9.0) (>= net462)) (&& (== net9.0) (< netcoreapp2.1)) (== netstandard2.0) (== netstandard2.1) | ||
System.Diagnostics.DiagnosticSource (9.0) | ||
System.Memory (>= 4.5.5) - restriction: || (&& (== net9.0) (>= net462)) (&& (== net9.0) (< net8.0)) (== netstandard2.0) (== netstandard2.1) | ||
System.Runtime.CompilerServices.Unsafe (>= 6.0) - restriction: || (&& (== net9.0) (>= net462)) (&& (== net9.0) (< net8.0)) (== netstandard2.0) (== netstandard2.1) | ||
System.IO.Pipelines (9.0) - restriction: || (&& (== net9.0) (>= net462)) (&& (== net9.0) (< net8.0)) (== netstandard2.0) (== netstandard2.1) | ||
System.Buffers (>= 4.5.1) - restriction: || (&& (== net9.0) (>= net462)) (&& (== net9.0) (< net8.0)) (== netstandard2.0) (== netstandard2.1) | ||
System.Memory (>= 4.5.5) - restriction: || (&& (== net9.0) (>= net462)) (&& (== net9.0) (< net8.0)) (== netstandard2.0) (== netstandard2.1) | ||
System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: || (&& (== net9.0) (>= net462)) (&& (== net9.0) (< net8.0)) (== netstandard2.0) (== netstandard2.1) | ||
System.Memory (4.6) - restriction: || (&& (== net9.0) (>= net462)) (&& (== net9.0) (< net8.0)) (== netstandard2.0) (== netstandard2.1) | ||
System.Buffers (>= 4.6) - restriction: || (&& (== net9.0) (>= net462)) (&& (== net9.0) (< netcoreapp2.1)) (== netstandard2.0) (== netstandard2.1) | ||
System.Numerics.Vectors (>= 4.6) - restriction: || (&& (== net9.0) (>= net462)) (&& (== net9.0) (< netcoreapp2.1)) (== netstandard2.0) (== netstandard2.1) | ||
System.Runtime.CompilerServices.Unsafe (>= 6.1) - restriction: || (&& (== net9.0) (>= net462)) (&& (== net9.0) (< netcoreapp2.1)) (== netstandard2.0) (== netstandard2.1) | ||
System.Numerics.Vectors (4.6) - restriction: || (&& (== net9.0) (>= net462)) (&& (== net9.0) (< netcoreapp2.1)) (== netstandard2.0) (== netstandard2.1) | ||
System.Runtime.CompilerServices.Unsafe (6.1) - restriction: || (&& (== net9.0) (>= net462)) (&& (== net9.0) (< net8.0)) (&& (== net9.0) (< netcoreapp2.1)) (== netstandard2.0) (== netstandard2.1) | ||
System.Text.Encodings.Web (9.0) - restriction: || (&& (== net9.0) (>= net462)) (&& (== net9.0) (< net8.0)) (== netstandard2.0) (== netstandard2.1) | ||
System.Buffers (>= 4.5.1) - restriction: || (&& (== net9.0) (>= net462)) (&& (== net9.0) (< net8.0)) (== netstandard2.0) (== netstandard2.1) | ||
System.Memory (>= 4.5.5) - restriction: || (&& (== net9.0) (>= net462)) (&& (== net9.0) (< net8.0)) (== netstandard2.0) (== netstandard2.1) | ||
System.Runtime.CompilerServices.Unsafe (>= 6.0) - restriction: || (&& (== net9.0) (>= net462)) (&& (== net9.0) (< net8.0)) (== netstandard2.0) (== netstandard2.1) | ||
System.Text.Json (9.0) | ||
Microsoft.Bcl.AsyncInterfaces (>= 9.0) - restriction: || (&& (== net9.0) (>= net462)) (&& (== net9.0) (< net8.0)) (== netstandard2.0) (== netstandard2.1) | ||
System.Buffers (>= 4.5.1) - restriction: || (&& (== net9.0) (>= net462)) (&& (== net9.0) (< net8.0)) (== netstandard2.0) (== netstandard2.1) | ||
System.IO.Pipelines (>= 9.0) - restriction: || (&& (== net9.0) (>= net462)) (&& (== net9.0) (< net8.0)) (== netstandard2.0) (== netstandard2.1) | ||
System.Memory (>= 4.5.5) - restriction: || (&& (== net9.0) (>= net462)) (&& (== net9.0) (< net8.0)) (== netstandard2.0) (== netstandard2.1) | ||
System.Runtime.CompilerServices.Unsafe (>= 6.0) - restriction: || (&& (== net9.0) (>= net462)) (&& (== net9.0) (< net8.0)) (== netstandard2.0) (== netstandard2.1) | ||
System.Text.Encodings.Web (>= 9.0) - restriction: || (&& (== net9.0) (>= net462)) (&& (== net9.0) (< net8.0)) (== netstandard2.0) (== netstandard2.1) | ||
System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: || (&& (== net9.0) (>= net462)) (&& (== net9.0) (< net8.0)) (== netstandard2.0) (== netstandard2.1) | ||
System.Threading.Tasks.Extensions (4.6) - restriction: || (&& (== net9.0) (>= net462)) (&& (== net9.0) (< net8.0)) (&& (== net9.0) (< netstandard2.1)) (== netstandard2.0) (== netstandard2.1) | ||
System.Runtime.CompilerServices.Unsafe (>= 6.1) - restriction: || (&& (== net9.0) (>= net462)) (&& (== net9.0) (< netcoreapp2.1)) (== netstandard2.0) (== netstandard2.1) | ||
Unquote (6.1) | ||
FSharp.Core (>= 4.7.2) | ||
GITHUB | ||
remote: eiriktsarpalis/TypeShape | ||
src/TypeShape/TypeShape.fs (6e7fe07c799de723de7e4b32d64a4fd6c1697c7f) | ||
GROUP Test | ||
RESTRICTION: == net8.0 | ||
RESTRICTION: == net9.0 | ||
NUGET | ||
remote: https://api.nuget.org/v3/index.json | ||
FsCheck (2.16.6) | ||
FSharp.Core (>= 4.2.3) | ||
FSharp.Core (8.0.100) | ||
Microsoft.CodeCoverage (17.8) | ||
Microsoft.NET.Test.Sdk (17.8) | ||
Microsoft.CodeCoverage (>= 17.8) | ||
Microsoft.TestPlatform.TestHost (>= 17.8) | ||
Microsoft.NETCore.Platforms (7.0.4) | ||
Microsoft.TestPlatform.ObjectModel (17.8) | ||
NuGet.Frameworks (>= 6.5) | ||
FSharp.Core (9.0.100) | ||
Microsoft.CodeCoverage (17.12) | ||
Microsoft.NET.Test.Sdk (17.12) | ||
Microsoft.CodeCoverage (>= 17.12) | ||
Microsoft.TestPlatform.TestHost (>= 17.12) | ||
Microsoft.TestPlatform.ObjectModel (17.12) | ||
System.Reflection.Metadata (>= 1.6) | ||
Microsoft.TestPlatform.TestHost (17.8) | ||
Microsoft.TestPlatform.ObjectModel (>= 17.8) | ||
Microsoft.TestPlatform.TestHost (17.12) | ||
Microsoft.TestPlatform.ObjectModel (>= 17.12) | ||
Newtonsoft.Json (>= 13.0.1) | ||
NETStandard.Library (2.0.3) | ||
Microsoft.NETCore.Platforms (>= 1.1) | ||
Newtonsoft.Json (13.0.3) | ||
NuGet.Frameworks (6.8) | ||
System.Collections.Immutable (8.0) | ||
System.Reflection.Metadata (8.0) | ||
System.Collections.Immutable (>= 8.0) | ||
xunit (2.6.2) | ||
xunit.analyzers (>= 1.6) | ||
xunit.assert (>= 2.6.2) | ||
xunit.core (2.6.2) | ||
System.Reflection.Metadata (9.0) | ||
xunit (2.9.2) | ||
xunit.analyzers (>= 1.16) | ||
xunit.assert (>= 2.9.2) | ||
xunit.core (2.9.2) | ||
xunit.abstractions (2.0.3) | ||
xunit.analyzers (1.6) | ||
xunit.assert (2.6.2) | ||
xunit.core (2.6.2) | ||
xunit.extensibility.core (2.6.2) | ||
xunit.extensibility.execution (2.6.2) | ||
xunit.extensibility.core (2.6.2) | ||
NETStandard.Library (>= 1.6.1) | ||
xunit.analyzers (1.18) | ||
xunit.assert (2.9.2) | ||
xunit.core (2.9.2) | ||
xunit.extensibility.core (2.9.2) | ||
xunit.extensibility.execution (2.9.2) | ||
xunit.extensibility.core (2.9.2) | ||
xunit.abstractions (>= 2.0.3) | ||
xunit.extensibility.execution (2.6.2) | ||
NETStandard.Library (>= 1.6.1) | ||
xunit.extensibility.core (2.6.2) | ||
xunit.runner.visualstudio (2.5.4) | ||
xunit.extensibility.execution (2.9.2) | ||
xunit.extensibility.core (2.9.2) | ||
xunit.runner.visualstudio (3.0) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
namespace FSharp.AWS.DynamoDB | ||
|
||
module Diagnostics = | ||
open System.Diagnostics | ||
open Amazon.DynamoDBv2.Model | ||
open System.Text.Json | ||
|
||
let private activitySource = new ActivitySource("FSharp.AWS.DynamoDB") | ||
|
||
let hasListeners () : bool = activitySource.HasListeners() | ||
|
||
let addActivityTags (tags: (string * obj) list) (activity: Activity) = | ||
if notNull activity then | ||
tags |> List.iter (fun (k, v) -> activity.AddTag(k, v) |> ignore) | ||
|
||
let startTableActivity (tableName: string) (operation: string) (tags: (string * obj) list) : Activity = | ||
let activity = activitySource.StartActivity(sprintf "%s %s" operation tableName, ActivityKind.Client) | ||
activity | ||
|> addActivityTags ( | ||
tags | ||
|> List.append | ||
[ ("db.system", "dynamodb") | ||
("aws.dynamodb.table_names", [| tableName |]) | ||
("rpc.system", "aws-api") | ||
("rpc.service", "DynamoDB") | ||
("rpc.method", operation) ] | ||
) | ||
activity | ||
|
||
let startMultipleTableActivity (tableNames: string seq) (operation: string) (tags: (string * obj) list) : Activity = | ||
let activity = activitySource.StartActivity(operation, ActivityKind.Client) | ||
activity | ||
|> addActivityTags ( | ||
tags | ||
|> List.append | ||
[ ("db.system", "dynamodb") | ||
("aws.dynamodb.table_names", tableNames |> Seq.toArray :> obj) | ||
("rpc.system", "aws-api") | ||
("rpc.service", "DynamoDB") | ||
("rpc.method", operation) ] | ||
) | ||
activity | ||
|
||
let addActivityCapacity (capacity: ConsumedCapacity seq) (activity: Activity) = | ||
if notNull activity then | ||
let value = capacity |> Seq.choose (function | null -> None | c -> Some (JsonSerializer.Serialize c)) |> Seq.toArray | ||
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. this fels wrong; surely there's a generic dictionary shape or something? or maybe it can be flattened into an entry per table, or... anything?! 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. I don’t like it either, but the semantic conventions specifically define it like this. It would make more sense to me to use dynamic attribute keys - I’m just as happy to leave it out, and maybe add metrics instead. 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. sgtm - I think iterative tweaks make sense for this sort of work anyway - no subsittute for using it IRL to make you realise what works and doesnt |
||
activity.AddTag("aws.dynamodb.consumed_capacity", value :> obj) |> ignore | ||
|
||
let addActivityException (ex: exn) (activity: Activity) = | ||
if notNull activity then | ||
activity.AddException ex |> ignore | ||
|
||
let stopActivity (activity: Activity) = | ||
if notNull activity then | ||
activity.Stop() | ||
|
||
module internal Task = | ||
open System.Threading.Tasks | ||
open System.Diagnostics | ||
|
||
/// Adds an exception to the activity if the task is faulted | ||
let addActivityException (activity: Activity) (task: Task<'a>) = | ||
if notNull activity && task.IsFaulted then | ||
let exn = | ||
if task.Exception.InnerExceptions.Count = 1 then | ||
task.Exception.InnerExceptions[0] | ||
else | ||
task.Exception | ||
Diagnostics.addActivityException exn activity | ||
task |
Uh oh!
There was an error while loading. Please reload this page.
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.
see also https://github.com/jet/equinox/blob/master/src/Equinox/Tracing.fs https://github.com/jet/equinox/blob/master/src/Equinox.MessageDb/Tracing.fs for other helper layout ideas
e.g. see how https://github.com/jet/equinox/blob/master/src/Equinox.MessageDb/MessageDb.fs#L251-L252 puts logic more in your face while still staying relatvely compact