diff --git a/src/Dependencies.props b/src/Dependencies.props
new file mode 100644
index 0000000..5154012
--- /dev/null
+++ b/src/Dependencies.props
@@ -0,0 +1,10 @@
+
+
+
+ 1.8.0
+ 11.0.0
+ 7.1.0
+ 4.7.0
+
+
+
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index d37e64d..da9e319 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -1,12 +1,47 @@
+
+
+
+
+ netstandard2.0
+
+
+
+ latest
+ 0.0.0
+ enable
+ nullable
+
+
- $(MSBuildThisFileDirectory.TrimEnd('\').TrimEnd('/'))
- $([System.IO.Path]::Combine($(CCSourceDirectory), 'Settings.props'))
- $([System.IO.Path]::Combine($(CCSourceDirectory), 'Version.props'))
- $([System.IO.Path]::Combine($(CCSourceDirectory), 'Package.props'))
+ Elastic APM .NET Agent Extensions
+ Swiss Life authors and contributors
+ Swiss Life
+ Copyright © $(Company) $([System.DateTime]::Now.Year)
+ https://github.com/SwissLife-OSS/elastic-apm-extensions/blob/master/LICENSE
+ https://github.com/SwissLife-OSS/elastic-apm-extensions
+ Release notes: https://github.com/SwissLife-OSS/elastic-apm-extensions/releases/$(Version)
+ true
+ https://github.com/SwissLife-OSS/elastic-apm-extensions/raw/master/logo.png
+ false
-
-
-
+
+ true
+ true
+ https://github.com/SwissLife-OSS/elastic-apm-extensions.git
+ GitHub
+ true
+ snupkg
+
+
+
+ portable
+ true
+
+
+
+
+
+
diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets
deleted file mode 100644
index 473fcc1..0000000
--- a/src/Directory.Build.targets
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/Elastic.Apm.Extensions.sln b/src/Elastic.Apm.Extensions.sln
new file mode 100644
index 0000000..b691caf
--- /dev/null
+++ b/src/Elastic.Apm.Extensions.sln
@@ -0,0 +1,51 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30907.101
+MinimumVisualStudioVersion = 15.0.26124.0
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elastic.Apm.GraphQL.HotChocolate", "Elastic.Apm.GraphQL.HotChocolate\Elastic.Apm.GraphQL.HotChocolate.csproj", "{FF6547C4-550A-4F3C-88AB-7DE2C88947C5}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elastic.Apm.Messaging.MassTransit", "Elastic.Apm.Messaging.MassTransit\Elastic.Apm.Messaging.MassTransit.csproj", "{9F5A0818-9E19-4B24-B955-4DBFE871271F}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {FF6547C4-550A-4F3C-88AB-7DE2C88947C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FF6547C4-550A-4F3C-88AB-7DE2C88947C5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FF6547C4-550A-4F3C-88AB-7DE2C88947C5}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {FF6547C4-550A-4F3C-88AB-7DE2C88947C5}.Debug|x64.Build.0 = Debug|Any CPU
+ {FF6547C4-550A-4F3C-88AB-7DE2C88947C5}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {FF6547C4-550A-4F3C-88AB-7DE2C88947C5}.Debug|x86.Build.0 = Debug|Any CPU
+ {FF6547C4-550A-4F3C-88AB-7DE2C88947C5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FF6547C4-550A-4F3C-88AB-7DE2C88947C5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FF6547C4-550A-4F3C-88AB-7DE2C88947C5}.Release|x64.ActiveCfg = Release|Any CPU
+ {FF6547C4-550A-4F3C-88AB-7DE2C88947C5}.Release|x64.Build.0 = Release|Any CPU
+ {FF6547C4-550A-4F3C-88AB-7DE2C88947C5}.Release|x86.ActiveCfg = Release|Any CPU
+ {FF6547C4-550A-4F3C-88AB-7DE2C88947C5}.Release|x86.Build.0 = Release|Any CPU
+ {9F5A0818-9E19-4B24-B955-4DBFE871271F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9F5A0818-9E19-4B24-B955-4DBFE871271F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9F5A0818-9E19-4B24-B955-4DBFE871271F}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {9F5A0818-9E19-4B24-B955-4DBFE871271F}.Debug|x64.Build.0 = Debug|Any CPU
+ {9F5A0818-9E19-4B24-B955-4DBFE871271F}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {9F5A0818-9E19-4B24-B955-4DBFE871271F}.Debug|x86.Build.0 = Debug|Any CPU
+ {9F5A0818-9E19-4B24-B955-4DBFE871271F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9F5A0818-9E19-4B24-B955-4DBFE871271F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9F5A0818-9E19-4B24-B955-4DBFE871271F}.Release|x64.ActiveCfg = Release|Any CPU
+ {9F5A0818-9E19-4B24-B955-4DBFE871271F}.Release|x64.Build.0 = Release|Any CPU
+ {9F5A0818-9E19-4B24-B955-4DBFE871271F}.Release|x86.ActiveCfg = Release|Any CPU
+ {9F5A0818-9E19-4B24-B955-4DBFE871271F}.Release|x86.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {F5A91904-BC2B-4796-8836-2FB19ADC7015}
+ EndGlobalSection
+EndGlobal
diff --git a/src/Elastic.Apm.GraphQL.HotChocolate/Directory.Build.props b/src/Elastic.Apm.GraphQL.HotChocolate/Directory.Build.props
new file mode 100644
index 0000000..0c0371b
--- /dev/null
+++ b/src/Elastic.Apm.GraphQL.HotChocolate/Directory.Build.props
@@ -0,0 +1,8 @@
+
+
+
+
+ apm monitoring elastic elasticapm analytics graphql hotchocolate
+
+
+
diff --git a/src/Elastic.Apm.GraphQL.HotChocolate/Elastic.Apm.GraphQL.HotChocolate.csproj b/src/Elastic.Apm.GraphQL.HotChocolate/Elastic.Apm.GraphQL.HotChocolate.csproj
new file mode 100644
index 0000000..5f616ca
--- /dev/null
+++ b/src/Elastic.Apm.GraphQL.HotChocolate/Elastic.Apm.GraphQL.HotChocolate.csproj
@@ -0,0 +1,19 @@
+
+
+
+ Elastic.Apm.GraphQL.HotChocolate
+ Elastic.Apm.GraphQL.HotChocolate
+ ElasticApm.GraphQL.HotChocolate
+ true
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Elastic.Apm.Internals/CompositeDisposable.cs b/src/Elastic.Apm.Internals/CompositeDisposable.cs
new file mode 100644
index 0000000..d8e01f6
--- /dev/null
+++ b/src/Elastic.Apm.Internals/CompositeDisposable.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+
+namespace Elastic.Apm
+{
+ internal sealed class CompositeDisposable : IDisposable
+ {
+ private readonly List _disposables = new List();
+ private readonly object _lock = new object();
+
+ private bool _isDisposed;
+
+ public void Dispose()
+ {
+ if (_isDisposed)
+ {
+ return;
+ }
+
+ lock (_lock)
+ {
+ if (_isDisposed)
+ {
+ return;
+ }
+
+ _isDisposed = true;
+
+ foreach (var d in _disposables)
+ {
+ d.Dispose();
+ }
+ }
+ }
+
+ public CompositeDisposable Add(IDisposable disposable)
+ {
+ if (_isDisposed)
+ {
+ throw new ObjectDisposedException(nameof(CompositeDisposable));
+ }
+
+ _disposables.Add(disposable);
+ return this;
+ }
+ }
+}
diff --git a/src/Elastic.Apm.Messaging.MassTransit/Constants.cs b/src/Elastic.Apm.Messaging.MassTransit/Constants.cs
new file mode 100644
index 0000000..cb2063f
--- /dev/null
+++ b/src/Elastic.Apm.Messaging.MassTransit/Constants.cs
@@ -0,0 +1,26 @@
+namespace Elastic.Apm.Messaging.MassTransit
+{
+ internal struct Constants
+ {
+ internal const string TraceHeaderName = "Elastic.Apm";
+
+ internal struct DiagnosticListener
+ {
+ internal const string Name = "MassTransit";
+ }
+
+ internal struct Events
+ {
+ internal const string SendStart = "MassTransit.Transport.Send.Start";
+ internal const string SendStop = "MassTransit.Transport.Send.Stop";
+ internal const string ReceiveStart = "MassTransit.Transport.Receive.Start";
+ internal const string ReceiveStop = "MassTransit.Transport.Receive.Stop";
+ }
+
+ internal struct Apm
+ {
+ internal const string Type = "messaging";
+ internal const string SendAction = "send";
+ }
+ }
+}
diff --git a/src/Elastic.Apm.Messaging.MassTransit/Directory.Build.props b/src/Elastic.Apm.Messaging.MassTransit/Directory.Build.props
new file mode 100644
index 0000000..d5c44cd
--- /dev/null
+++ b/src/Elastic.Apm.Messaging.MassTransit/Directory.Build.props
@@ -0,0 +1,8 @@
+
+
+
+
+ apm monitoring elastic elasticapm analytics messaging masstransit
+
+
+
diff --git a/src/Elastic.Apm.Messaging.MassTransit/Elastic.Apm.Messaging.MassTransit.csproj b/src/Elastic.Apm.Messaging.MassTransit/Elastic.Apm.Messaging.MassTransit.csproj
new file mode 100644
index 0000000..20c8c55
--- /dev/null
+++ b/src/Elastic.Apm.Messaging.MassTransit/Elastic.Apm.Messaging.MassTransit.csproj
@@ -0,0 +1,20 @@
+
+
+
+ Elastic.Apm.Messaging.MassTransit
+ Elastic.Apm.Messaging.MassTransit
+ ElasticApm.Messaging.MassTransit
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Elastic.Apm.Messaging.MassTransit/MassTransitDiagnosticInitializer.cs b/src/Elastic.Apm.Messaging.MassTransit/MassTransitDiagnosticInitializer.cs
new file mode 100644
index 0000000..b5b87d5
--- /dev/null
+++ b/src/Elastic.Apm.Messaging.MassTransit/MassTransitDiagnosticInitializer.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Diagnostics;
+
+namespace Elastic.Apm.Messaging.MassTransit
+{
+ internal class MassTransitDiagnosticInitializer : IObserver, IDisposable
+ {
+ private readonly IApmAgent _apmAgent;
+ private IDisposable? _sourceSubscription;
+
+ internal MassTransitDiagnosticInitializer(IApmAgent apmAgent)
+ {
+ _apmAgent = apmAgent;
+ }
+
+ public void Dispose() => _sourceSubscription?.Dispose();
+
+ public void OnCompleted()
+ {
+ }
+
+ public void OnError(Exception error)
+ {
+ }
+
+ public void OnNext(DiagnosticListener value)
+ {
+ if (string.Equals(value.Name, Constants.DiagnosticListener.Name,
+ StringComparison.InvariantCultureIgnoreCase))
+ {
+ _sourceSubscription = value.Subscribe(new MassTransitDiagnosticListener(_apmAgent));
+ }
+ }
+ }
+}
diff --git a/src/Elastic.Apm.Messaging.MassTransit/MassTransitDiagnosticListener.cs b/src/Elastic.Apm.Messaging.MassTransit/MassTransitDiagnosticListener.cs
new file mode 100644
index 0000000..f24ed55
--- /dev/null
+++ b/src/Elastic.Apm.Messaging.MassTransit/MassTransitDiagnosticListener.cs
@@ -0,0 +1,135 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using Elastic.Apm.Api;
+using Elastic.Apm.Logging;
+using MassTransit;
+
+namespace Elastic.Apm.Messaging.MassTransit
+{
+ internal class MassTransitDiagnosticListener : IObserver>
+ {
+ private readonly IApmAgent _apmAgent;
+ private readonly IApmLogger _logger;
+
+ private readonly ConcurrentDictionary _activities =
+ new ConcurrentDictionary();
+
+
+ internal MassTransitDiagnosticListener(IApmAgent apmAgent)
+ {
+ _apmAgent = apmAgent;
+ _logger = apmAgent.Logger;
+ }
+
+ public void OnNext(KeyValuePair value)
+ {
+ if (!HasActivity(value.Key, out Activity? activity))
+ {
+ return;
+ }
+
+ switch (value.Key)
+ {
+ case Constants.Events.SendStart:
+ HandleSendStart(activity, value.Value);
+ return;
+ case Constants.Events.SendStop:
+ HandleStop(activity.SpanId, activity.Duration);
+ return;
+ case Constants.Events.ReceiveStart:
+ HandleReceiveStart(activity, value.Value);
+ return;
+ case Constants.Events.ReceiveStop:
+ HandleStop(activity.ParentSpanId, activity.Parent!.Duration);
+ return;
+ }
+ }
+
+ public void OnError(Exception error)
+ {
+ }
+
+ public void OnCompleted()
+ {
+ }
+
+ private void HandleSendStart(Activity activity, object? context)
+ {
+ try
+ {
+ IExecutionSegment? executionSegment = _apmAgent.Tracer.GetExecutionSegment();
+ if (executionSegment != null && context is SendContext sendContext)
+ {
+ var spanName = context is PublishContext ? "Publish" : "Send";
+ spanName = $"{spanName} {sendContext.DestinationAddress.AbsolutePath}";
+ var subType = sendContext.DestinationAddress.Scheme;
+
+ ISpan span = executionSegment.StartSpan(
+ spanName,
+ Constants.Apm.Type,
+ subType,
+ Constants.Apm.SendAction);
+
+ sendContext.SetTracingData(span);
+
+ _activities.TryAdd(activity.SpanId, span);
+ }
+ }
+ catch (Exception ex)
+ {
+ var message = $"{Constants.Events.SendStart} instrumentation failed.";
+ _logger.Log(LogLevel.Error, message, ex, default);
+ }
+ }
+
+ private void HandleReceiveStart(Activity activity, object? context)
+ {
+ try
+ {
+ if (context is ReceiveContext receiveContext)
+ {
+ DistributedTracingData? tracingData = receiveContext.GetTracingData();
+ var transactionName = $"Receive {receiveContext.InputAddress.AbsolutePath}";
+
+ ITransaction transaction = _apmAgent.Tracer.StartTransaction(
+ transactionName,
+ Constants.Apm.Type,
+ tracingData);
+
+ _activities.TryAdd(activity.SpanId, transaction);
+ }
+ }
+ catch (Exception ex)
+ {
+ var message = $"{Constants.Events.ReceiveStart} instrumentation failed.";
+ _logger.Log(LogLevel.Error, message, ex, default);
+ }
+ }
+
+ private void HandleStop(ActivitySpanId? spanId, TimeSpan duration)
+ {
+ if (spanId.HasValue &&
+ _activities.TryRemove(spanId.Value, out IExecutionSegment executionSegment))
+ {
+ executionSegment.Duration = duration.TotalMilliseconds;
+ executionSegment.End();
+ }
+ }
+
+ private bool HasActivity(string eventName, [NotNullWhen(true)] out Activity? activity)
+ {
+ activity = Activity.Current;
+ if (activity == null)
+ {
+ var message = $"No activity was found for event: {eventName}";
+ _logger.Log(LogLevel.Warning, message, default, default);
+ return false;
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/src/Elastic.Apm.Messaging.MassTransit/MassTransitDiagnosticsSubscriber.cs b/src/Elastic.Apm.Messaging.MassTransit/MassTransitDiagnosticsSubscriber.cs
new file mode 100644
index 0000000..7d2e931
--- /dev/null
+++ b/src/Elastic.Apm.Messaging.MassTransit/MassTransitDiagnosticsSubscriber.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Diagnostics;
+using Elastic.Apm.DiagnosticSource;
+
+namespace Elastic.Apm.Messaging.MassTransit
+{
+ ///
+ /// Diagnostic events subscriber for MassTransit.
+ ///
+ public class MassTransitDiagnosticsSubscriber : IDiagnosticsSubscriber
+ {
+ ///
+ public IDisposable Subscribe(IApmAgent components)
+ {
+ var compositeDisposable = new CompositeDisposable();
+
+ if (!components.ConfigurationReader.Enabled)
+ {
+ return compositeDisposable;
+ }
+
+ var initializer = new MassTransitDiagnosticInitializer(components);
+ compositeDisposable.Add(initializer);
+ compositeDisposable.Add(DiagnosticListener.AllListeners.Subscribe(initializer));
+
+ return compositeDisposable;
+ }
+ }
+}
diff --git a/src/Elastic.Apm.Messaging.MassTransit/MassTransitExtensions.cs b/src/Elastic.Apm.Messaging.MassTransit/MassTransitExtensions.cs
new file mode 100644
index 0000000..9a28013
--- /dev/null
+++ b/src/Elastic.Apm.Messaging.MassTransit/MassTransitExtensions.cs
@@ -0,0 +1,20 @@
+using Elastic.Apm.Api;
+using MassTransit;
+
+namespace Elastic.Apm.Messaging.MassTransit
+{
+ internal static class MassTransitExtensions
+ {
+ internal static void SetTracingData(this SendContext context, ISpan span)
+ {
+ var tracingData = span.OutgoingDistributedTracingData.SerializeToString();
+ context.Headers.Set(Constants.TraceHeaderName, tracingData);
+ }
+
+ internal static DistributedTracingData? GetTracingData(this ReceiveContext context)
+ {
+ var tracingData = context.TransportHeaders.Get(Constants.TraceHeaderName);
+ return DistributedTracingData.TryDeserializeFromString(tracingData);
+ }
+ }
+}
diff --git a/src/Nullable.cs b/src/Nullable.cs
new file mode 100644
index 0000000..fea248e
--- /dev/null
+++ b/src/Nullable.cs
@@ -0,0 +1,135 @@
+#pragma warning disable MA0048 // File name must match type name
+#define INTERNAL_NULLABLE_ATTRIBUTES
+#if NETSTANDARD2_0 || NETCOREAPP2_0 || NETCOREAPP2_1 || NETCOREAPP2_2 || NET45 || NET451 || NET452 || NET6 || NET461 || NET462 || NET47 || NET471 || NET472 || NET48
+
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+// This code was copied from https://raw.githubusercontent.com/dotnet/corefx/48363ac826ccf66fbe31a5dcb1dc2aab9a7dd768/src/Common/src/CoreLib/System/Diagnostics/CodeAnalysis/NullableAttributes.cs
+
+namespace System.Diagnostics.CodeAnalysis
+{
+ /// Specifies that null is allowed as an input even if the corresponding type disallows it.
+ [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)]
+#if INTERNAL_NULLABLE_ATTRIBUTES
+ internal
+#else
+ public
+#endif
+ sealed class AllowNullAttribute : Attribute { }
+
+ /// Specifies that null is disallowed as an input even if the corresponding type allows it.
+ [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)]
+#if INTERNAL_NULLABLE_ATTRIBUTES
+ internal
+#else
+ public
+#endif
+ sealed class DisallowNullAttribute : Attribute { }
+
+ /// Specifies that an output may be null even if the corresponding type disallows it.
+ [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)]
+#if INTERNAL_NULLABLE_ATTRIBUTES
+ internal
+#else
+ public
+#endif
+ sealed class MaybeNullAttribute : Attribute { }
+
+ /// Specifies that an output will not be null even if the corresponding type allows it.
+ [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)]
+#if INTERNAL_NULLABLE_ATTRIBUTES
+ internal
+#else
+ public
+#endif
+ sealed class NotNullAttribute : Attribute { }
+
+ /// Specifies that when a method returns , the parameter may be null even if the corresponding type disallows it.
+ [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
+#if INTERNAL_NULLABLE_ATTRIBUTES
+ internal
+#else
+ public
+#endif
+ sealed class MaybeNullWhenAttribute : Attribute
+ {
+ /// Initializes the attribute with the specified return value condition.
+ ///
+ /// The return value condition. If the method returns this value, the associated parameter may be null.
+ ///
+ public MaybeNullWhenAttribute(bool returnValue) => ReturnValue = returnValue;
+
+ /// Gets the return value condition.
+ public bool ReturnValue { get; }
+ }
+
+ /// Specifies that when a method returns , the parameter will not be null even if the corresponding type allows it.
+ [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
+#if INTERNAL_NULLABLE_ATTRIBUTES
+ internal
+#else
+ public
+#endif
+ sealed class NotNullWhenAttribute : Attribute
+ {
+ /// Initializes the attribute with the specified return value condition.
+ ///
+ /// The return value condition. If the method returns this value, the associated parameter will not be null.
+ ///
+ public NotNullWhenAttribute(bool returnValue) => ReturnValue = returnValue;
+
+ /// Gets the return value condition.
+ public bool ReturnValue { get; }
+ }
+
+ /// Specifies that the output will be non-null if the named parameter is non-null.
+ [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)]
+#if INTERNAL_NULLABLE_ATTRIBUTES
+ internal
+#else
+ public
+#endif
+ sealed class NotNullIfNotNullAttribute : Attribute
+ {
+ /// Initializes the attribute with the associated parameter name.
+ ///
+ /// The associated parameter name. The output will be non-null if the argument to the parameter specified is non-null.
+ ///
+ public NotNullIfNotNullAttribute(string parameterName) => ParameterName = parameterName;
+
+ /// Gets the associated parameter name.
+ public string ParameterName { get; }
+ }
+
+ /// Applied to a method that will never return under any circumstance.
+ [AttributeUsage(AttributeTargets.Method, Inherited = false)]
+#if INTERNAL_NULLABLE_ATTRIBUTES
+ internal
+#else
+ public
+#endif
+ sealed class DoesNotReturnAttribute : Attribute { }
+
+ /// Specifies that the method will not return if the associated Boolean parameter is passed the specified value.
+ [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
+#if INTERNAL_NULLABLE_ATTRIBUTES
+ internal
+#else
+ public
+#endif
+ sealed class DoesNotReturnIfAttribute : Attribute
+ {
+ /// Initializes the attribute with the specified parameter value.
+ ///
+ /// The condition parameter value. Code after the method will be considered unreachable by diagnostics if the argument to
+ /// the associated parameter matches this value.
+ ///
+ public DoesNotReturnIfAttribute(bool parameterValue) => ParameterValue = parameterValue;
+
+ /// Gets the condition parameter value.
+ public bool ParameterValue { get; }
+ }
+}
+
+#endif
diff --git a/src/Nullable.props b/src/Nullable.props
new file mode 100644
index 0000000..30b4f1b
--- /dev/null
+++ b/src/Nullable.props
@@ -0,0 +1,9 @@
+
+
+ $(NoWarn);8600;8601;8602;8603;8604;CS0436
+
+
+
+
+
+
diff --git a/src/Package.props b/src/Package.props
deleted file mode 100644
index f80396a..0000000
--- a/src/Package.props
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
- {Placeholder}-
- Swiss Life authors and contributors
- Swiss Life
- Copyright © 2019 Swiss Life
- https://github.com/SwissLife-OSS/{Placeholder}/blob/master/LICENSE
- https://github.com/SwissLife-OSS/{Placeholder}
- Release notes: https://github.com/SwissLife-OSS/{Placeholder}/releases/$(Version)
- {Placeholder}
- true
- https://github.com/SwissLife-OSS/{Placeholder}/raw/master/logo.png
- false
-
-
-
- true
- true
- https://github.com/SwissLife-OSS/{Placeholder}.git
- GitHub
- true
- snupkg
- $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb
-
-
-
-
-
-
-
diff --git a/src/Shared/TracerExtensions.cs b/src/Shared/TracerExtensions.cs
new file mode 100644
index 0000000..e37a0bb
--- /dev/null
+++ b/src/Shared/TracerExtensions.cs
@@ -0,0 +1,13 @@
+using Elastic.Apm.Api;
+
+namespace Elastic.Apm
+{
+ internal static class TracerExtensions
+ {
+ public static IExecutionSegment? GetExecutionSegment(this ITracer tracer)
+ {
+ ITransaction? transaction = tracer.CurrentTransaction;
+ return tracer.CurrentSpan ?? (IExecutionSegment)transaction;
+ }
+ }
+}
diff --git a/src/Version.props b/src/Version.props
deleted file mode 100644
index 1f8399b..0000000
--- a/src/Version.props
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
- 0.0.0
-
-
-
\ No newline at end of file