Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/test-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,9 @@ jobs:
icacls C:\Windows\Temp /grant "IUSR:(OI)(CI)F" /T
icacls "c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files" /grant "IUSR:(OI)(CI)F" /T

# The test filter here is intentional.
# The IIS tests are slow and quite flaky so we only run one of them in CI, as a smoke test
# to verify that the IIS integration works.
- name: Run tests
run: |
set ELASTIC_APM_TESTS_FULL_FRAMEWORK_ENABLED=true
Expand Down
2 changes: 1 addition & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@
<PackageVersion Include="System.CommandLine" Version="2.0.0-beta1.20427.1" />
<PackageVersion Include="System.Data.SQLite" Version="1.0.112" />
<PackageVersion Include="System.Data.SqlClient" Version="4.8.6" />
<PackageVersion Include="System.Diagnostics.DiagnosticSource" Version="5.0.0" />
<PackageVersion Include="System.Diagnostics.DiagnosticSource" Version="8.0.1" />
<PackageVersion Include="System.Diagnostics.PerformanceCounter" Version="6.0.1" />
<PackageVersion Include="System.IO.FileSystem.AccessControl" Version="4.7.0" />
<PackageVersion Include="System.Reflection.Emit" Version="4.3.0" />
Expand Down
71 changes: 24 additions & 47 deletions build/scripts/Build.fs
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,14 @@ open Scripts.TestEnvironment
open Tooling

module Build =

let private oldDiagnosticSourceVersion = SemVer.parse "4.6.0"
let private diagnosticSourceVersion6 = SemVer.parse "6.0.0"

let mutable private currentDiagnosticSourceVersion = None

let private oldDiagnosticSourceVersion = SemVer.parse "6.0.0"
let mutable private currentDiagnosticSourceVersion = None

let private aspNetFullFramework = Paths.IntegrationsProjFile "Elastic.Apm.AspNetFullFramework"

let private allSrcProjects = !! "src/**/*.csproj"

let private fullFrameworkProjects = [
aspNetFullFramework
Paths.TestProjFile "Elastic.Apm.AspNetFullFramework.Tests"
Paths.SampleProjFile "AspNetFullFrameworkSampleApp"
]

/// Gets all the Target Frameworks from a project file
let private getAllTargetFrameworks (p: string) =
let doc = XElement.Load p
Expand Down Expand Up @@ -83,21 +75,19 @@ module Build =
DisableInternalBinLog = true
NoLogo = true
}) projectOrSln

/// Gets the current version of System.Diagnostics.DiagnosticSource referenced by Elastic.Apm
let getCurrentApmDiagnosticSourceVersion =
match currentDiagnosticSourceVersion with
| Some v -> v
| None ->
let xml = XDocument.Load("Directory.Packages.props")
let package = xml.XPathSelectElement("//PackageVersion[@Include='System.Diagnostics.DiagnosticSource']")
let xml = XDocument.Load "Directory.Packages.props"
let package = xml.XPathSelectElement "//PackageVersion[@Include='System.Diagnostics.DiagnosticSource']"
let version = package.Attribute("Version").Value
let version = SemVer.parse version
currentDiagnosticSourceVersion <- Some(version)
version

let private majorVersions = Dictionary<SemVerInfo, SemVerInfo>()


/// Publishes specific projects with specific DiagnosticSource versions
let private publishProjectsWithDiagnosticSourceVersion projects version =
projects
Expand All @@ -110,8 +100,8 @@ module Build =
|> (fun p -> sprintf "%s_%i.0.0/%s" p version.Major framework)
|> Paths.BuildOutput
|> Path.GetFullPath
printfn "Publishing %s %s with System.Diagnostics.DiagnosticSource %O..." proj framework version

printfn "Publishing %s %s with System.Diagnostics.DiagnosticSource %O to %s..." proj framework version output
DotNet.Exec ["publish" ; proj
sprintf "\"/p:DiagnosticSourceVersion=%O\"" version
"-c"; "Release"
Expand All @@ -121,21 +111,15 @@ module Build =
"--nologo"; "--force"]
)
)


/// Publishes ElasticApmStartupHook against a 4.x and 6.x version of System.Diagnostics.DiagnosticSource
/// Publishes ElasticApmStartupHook against an older version of System.Diagnostics.DiagnosticSource
let private publishElasticApmStartupHookWithDiagnosticSourceVersion () =
let projects =
!! (Paths.SrcProjFile "Elastic.Apm")
++ (Paths.StartupHookProjFile "Elastic.Apm.StartupHook.Loader")
++ Paths.StartupHookProjFile "Elastic.Apm.StartupHook.Loader"

publishProjectsWithDiagnosticSourceVersion projects oldDiagnosticSourceVersion

let elasticApmProj =
!! (Paths.SrcProjFile "Elastic.Apm")

publishProjectsWithDiagnosticSourceVersion elasticApmProj diagnosticSourceVersion6


/// Runs dotnet build on all .NET core projects in the solution.
/// When running on Windows and not CI, also runs MSBuild Build on .NET Framework
let Build () =
Expand Down Expand Up @@ -226,8 +210,6 @@ module Build =
DotNet.Exec ["publish" ; proj; "-c"; "Release"; "-f"; framework; "-v"; "q"; "--nologo"; $"--property:PublishDir=%s{output}"]
)
)

publishElasticApmStartupHookWithDiagnosticSourceVersion()

/// Packages projects into nuget packages
let Pack () =
Expand Down Expand Up @@ -258,7 +240,9 @@ module Build =
|> Seq.iter (fun file -> file.CopyTo(Path.combine destination.FullName file.Name, true) |> ignore)

/// Creates versioned ElasticApmAgent.zip file
let AgentZip () =
let AgentZip () =
publishElasticApmStartupHookWithDiagnosticSourceVersion()

let name = "ElasticApmAgent"
let currentAssemblyVersion = Versioning.CurrentVersion.FileVersion
let versionedName =
Expand All @@ -267,33 +251,26 @@ module Build =
let agentDir = Paths.BuildOutput name |> DirectoryInfo
agentDir.Create()

// copy startup hook to root of agent directory
// Copy startup hook to root of agent directory
!! (Paths.BuildOutput "ElasticApmAgentStartupHook/netstandard2.0")
|> Seq.filter Path.isDirectory
|> Seq.map DirectoryInfo
|> Seq.iter (copyDllsAndPdbs agentDir)

// assemblies compiled against "current" version of System.Diagnostics.DiagnosticSource
!! (Paths.BuildOutput "Elastic.Apm.StartupHook.Loader/netstandard2.0")
++ (Paths.BuildOutput "Elastic.Apm/netstandard2.0")
// Copy assemblies compiled against latest target and "current" version of System.Diagnostics.DiagnosticSource
!! (Paths.BuildOutput "Elastic.Apm.StartupHook.Loader/netstandard2.1")
++ Paths.BuildOutput "Elastic.Apm/net8.0"
|> Seq.filter Path.isDirectory
|> Seq.map DirectoryInfo
|> Seq.iter (copyDllsAndPdbs (agentDir.CreateSubdirectory(sprintf "%i.0.0" getCurrentApmDiagnosticSourceVersion.Major)))
// assemblies compiled against older version of System.Diagnostics.DiagnosticSource
!! (Paths.BuildOutput (sprintf "Elastic.Apm.StartupHook.Loader_%i.0.0/netstandard2.0" oldDiagnosticSourceVersion.Major))
++ (Paths.BuildOutput (sprintf "Elastic.Apm_%i.0.0/netstandard2.0" oldDiagnosticSourceVersion.Major))

// Copy assemblies compiled against older version of System.Diagnostics.DiagnosticSource
!! (Paths.BuildOutput (sprintf "Elastic.Apm.StartupHook.Loader_%i.0.0/netstandard2.1" oldDiagnosticSourceVersion.Major))
++ Paths.BuildOutput (sprintf "Elastic.Apm_%i.0.0/netstandard2.1" oldDiagnosticSourceVersion.Major)
|> Seq.filter Path.isDirectory
|> Seq.map DirectoryInfo
|> Seq.iter (copyDllsAndPdbs (agentDir.CreateSubdirectory(sprintf "%i.0.0" oldDiagnosticSourceVersion.Major)))

// assemblies compiled against 6.0 version of System.Diagnostics.DiagnosticSource
!! (Paths.BuildOutput (sprintf "Elastic.Apm.StartupHook.Loader_%i.0.0/netstandard2.0" oldDiagnosticSourceVersion.Major))
++ (Paths.BuildOutput (sprintf "Elastic.Apm_%i.0.0/net8.0" diagnosticSourceVersion6.Major))
|> Seq.filter Path.isDirectory
|> Seq.map DirectoryInfo
|> Seq.iter (copyDllsAndPdbs (agentDir.CreateSubdirectory(sprintf "%i.0.0" diagnosticSourceVersion6.Major)))


// include version in the zip file name
ZipFile.CreateFromDirectory(agentDir.FullName, Paths.BuildOutput versionedName + ".zip")

Expand Down
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"sdk": {
"version": "8.0.404",
"version": "9.0.303",
"rollForward": "latestFeature",
"allowPrerelease": false
}
Expand Down
2 changes: 0 additions & 2 deletions sample/ApiSamples/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -314,11 +314,9 @@ public static void SampleSpanWithCustomContextFillAll()
// ReSharper restore ArrangeMethodOrOperatorBody
#pragma warning restore IDE0022

#if NET8_0_OR_GREATER
/// <summary>
/// Test for https://github.com/elastic/apm-agent-dotnet/issues/884
/// </summary>
private IAsyncEnumerable<int> TestCompilation() => throw new Exception();
#endif
}
}
36 changes: 22 additions & 14 deletions src/Elastic.Apm/AgentComponents.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
using Elastic.Apm.Logging;
using Elastic.Apm.Metrics;
using Elastic.Apm.Metrics.MetricsProvider;
using Elastic.Apm.Model;
using Elastic.Apm.Report;
using Elastic.Apm.ServerInfo;

#if NET8_0_OR_GREATER
#if NET || NETSTANDARD2_1
using Elastic.Apm.OpenTelemetry;
using Elastic.Apm.Model;
#endif

#if NETFRAMEWORK
Expand Down Expand Up @@ -62,9 +62,9 @@ internal AgentComponents(
ApmServerInfo = apmServerInfo ?? new ApmServerInfo();
HttpTraceConfiguration = new HttpTraceConfiguration();

#if NET
// Initialize early because ServerInfoCallback requires it and might execute
// before EnsureElasticActivityStarted runs
#if NET || NETSTANDARD2_1
ElasticActivityListener = new ElasticActivityListener(this, HttpTraceConfiguration);

// Ensure we have a listener so that transaction activities are created when the OTel bridge is disabled
Expand All @@ -73,6 +73,7 @@ internal AgentComponents(
ActivitySource.AddActivityListener(Transaction.Listener);
}
#endif

var systemInfoHelper = new SystemInfoHelper(Logger);
var system = systemInfoHelper.GetSystemInfo(Configuration.HostName, hostNameDetector);

Expand Down Expand Up @@ -124,11 +125,18 @@ internal AgentComponents(

private void EnsureElasticActivityListenerStarted()
{
#if !NET
if (!Configuration.OpenTelemetryBridgeEnabled)
return;

#if NETFRAMEWORK
Logger.Info()
?.Log(
"OpenTelemetry (Activity) bridge is not supported on .NET Framework - bridge won't be enabled. Current Server version: {version}",
ApmServerInfo.Version?.ToString() ?? "unknown");
return;
#else
if (!Configuration.OpenTelemetryBridgeEnabled) return;
#endif

#if NET || NETSTANDARD2_1
// If the server version is not known yet, we enable the listener - and then the callback will do the version check once we have the version
if (ApmServerInfo.Version == null || ApmServerInfo.Version == new ElasticVersion(0, 0, 0, null))
ElasticActivityListener?.Start(TracerInternal);
Expand All @@ -151,10 +159,8 @@ private void EnsureElasticActivityListenerStarted()

private void ServerInfoCallback(bool success, IApmServerInfo serverInfo)
{
#if !NET8_0_OR_GREATER
return;
#else
if (!Configuration.OpenTelemetryBridgeEnabled) return;
if (!Configuration.OpenTelemetryBridgeEnabled)
return;

if (success)
{
Expand All @@ -170,7 +176,9 @@ private void ServerInfoCallback(bool success, IApmServerInfo serverInfo)
?.Log(
"OpenTelemetry (Activity) bridge is only supported with APM Server 7.16.0 or newer - bridge won't be enabled. Current Server version: {version}",
serverInfo.Version.ToString());
ElasticActivityListener?.Dispose();
#if NET || NETSTANDARD2_1
ElasticActivityListener?.Dispose();
#endif
}
}
else
Expand All @@ -180,7 +188,6 @@ private void ServerInfoCallback(bool success, IApmServerInfo serverInfo)
"Unable to read server version - OpenTelemetry (Activity) bridge is only supported with APM Server 7.16.0 or newer. "
+ "The bridge remains active, but due to unknown server version it may not work as expected.");
}
#endif
}
#pragma warning disable IDE0022
private static IApmLogger DefaultLogger(IApmLogger logger, IConfigurationReader configurationReader)
Expand Down Expand Up @@ -243,7 +250,7 @@ internal static IApmLogger GetGlobalLogger(IApmLogger fallbackLogger, LogLevel a
return fallbackLogger;
}

#if NET
#if NET || NETSTANDARD2_1
private ElasticActivityListener ElasticActivityListener { get; }
#endif

Expand Down Expand Up @@ -286,8 +293,9 @@ public void Dispose()

if (PayloadSender is IDisposable disposablePayloadSender)
disposablePayloadSender.Dispose();

CentralConfigurationFetcher?.Dispose();
#if NET8_0_OR_GREATER
#if NET || NETSTANDARD2_1
ElasticActivityListener?.Dispose();
#endif
}
Expand Down
14 changes: 7 additions & 7 deletions src/Elastic.Apm/Api/IExecutionSegment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public interface IExecutionSegment
/// <summary>
/// The outcome of the IExecutionSegment: success, failure, or unknown.
/// </summary>
public Outcome Outcome { get; set; }
Outcome Outcome { get; set; }

/// <summary>
/// Distributed tracing data for this segment as the distributed tracing caller.
Expand Down Expand Up @@ -297,7 +297,7 @@ Task<T> CaptureSpan<T>(string name, string type, Func<ISpan, Task<T>> func, stri
/// <inheritdoc cref="SetLabel(string,bool)" />
/// </param>
/// </summary>
public void SetLabel(string key, string value);
void SetLabel(string key, string value);

/// <summary>
/// Labels are used to add indexed information to transactions, spans, and errors. Indexed means the data is searchable and
Expand All @@ -308,7 +308,7 @@ Task<T> CaptureSpan<T>(string name, string type, Func<ISpan, Task<T>> func, stri
/// with underscores.
/// </param>
/// <param name="value">The value of the label</param>
public void SetLabel(string key, bool value);
void SetLabel(string key, bool value);

/// <summary>
/// <inheritdoc cref="SetLabel(string,bool)" />
Expand All @@ -319,7 +319,7 @@ Task<T> CaptureSpan<T>(string name, string type, Func<ISpan, Task<T>> func, stri
/// <param name="value">
/// <inheritdoc cref="SetLabel(string,bool)" />
/// </param>
public void SetLabel(string key, double value);
void SetLabel(string key, double value);

/// <summary>
/// <inheritdoc cref="SetLabel(string,bool)" />
Expand All @@ -330,7 +330,7 @@ Task<T> CaptureSpan<T>(string name, string type, Func<ISpan, Task<T>> func, stri
/// <param name="value">
/// <inheritdoc cref="SetLabel(string,bool)" />
/// </param>
public void SetLabel(string key, int value);
void SetLabel(string key, int value);

/// <summary>
/// <inheritdoc cref="SetLabel(string,bool)" />
Expand All @@ -341,7 +341,7 @@ Task<T> CaptureSpan<T>(string name, string type, Func<ISpan, Task<T>> func, stri
/// <param name="value">
/// <inheritdoc cref="SetLabel(string,bool)" />
/// </param>
public void SetLabel(string key, long value);
void SetLabel(string key, long value);

/// <summary>
/// <inheritdoc cref="SetLabel(string,bool)" />
Expand All @@ -352,7 +352,7 @@ Task<T> CaptureSpan<T>(string name, string type, Func<ISpan, Task<T>> func, stri
/// <param name="value">
/// <inheritdoc cref="SetLabel(string,bool)" />
/// </param>
public void SetLabel(string key, decimal value);
void SetLabel(string key, decimal value);

/// <summary>
/// Start and return a new custom span as a child of this execution segment.
Expand Down
2 changes: 1 addition & 1 deletion src/Elastic.Apm/Api/ISpan.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public interface ISpan : IExecutionSegment
/// <summary>
/// Indicates that this span is an exit span.
/// </summary>
public bool IsExitSpan { get; }
bool IsExitSpan { get; }

/// <summary>
/// The stack trace which was captured for the given span.
Expand Down
4 changes: 2 additions & 2 deletions src/Elastic.Apm/Api/ITransaction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public interface ITransaction : IExecutionSegment
/// <summary>
/// Contains data related to FaaS (Function as a Service) events.
/// </summary>
public Faas FaaS { get; set; }
Faas FaaS { get; set; }

/// <summary>
/// Any arbitrary contextual information regarding the event, captured by the agent, optionally provided by the user.
Expand All @@ -46,7 +46,7 @@ public interface ITransaction : IExecutionSegment
/// A snapshot of configuration from when the transaction started. A snapshot contains values
/// from initial configuration combined with dynamic values from central configuration, if enabled.
/// </summary>
public IConfiguration Configuration { get; }
IConfiguration Configuration { get; }

/// <summary>
/// A string describing the result of the transaction.
Expand Down
Loading
Loading