diff --git a/Elastic.OpenTelemetry.sln b/Elastic.OpenTelemetry.sln
index 688c3f2..58b5a84 100644
--- a/Elastic.OpenTelemetry.sln
+++ b/Elastic.OpenTelemetry.sln
@@ -45,6 +45,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Example.AutoInstrumentation
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoInstrumentation.IntegrationTests", "tests\AutoInstrumentation.IntegrationTests\AutoInstrumentation.IntegrationTests.csproj", "{782E4DC1-8186-4BAC-B2F4-89E6DF22A4DD}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elastic.OpenTelemetry.AutoInstrumentation", "src\Elastic.OpenTelemetry.AutoInstrumentation\Elastic.OpenTelemetry.AutoInstrumentation.csproj", "{B1CA9165-89D9-4D6E-AFEF-5434A8D8A672}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -107,6 +109,10 @@ Global
{782E4DC1-8186-4BAC-B2F4-89E6DF22A4DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{782E4DC1-8186-4BAC-B2F4-89E6DF22A4DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{782E4DC1-8186-4BAC-B2F4-89E6DF22A4DD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B1CA9165-89D9-4D6E-AFEF-5434A8D8A672}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B1CA9165-89D9-4D6E-AFEF-5434A8D8A672}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B1CA9165-89D9-4D6E-AFEF-5434A8D8A672}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B1CA9165-89D9-4D6E-AFEF-5434A8D8A672}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -123,6 +129,7 @@ Global
{A3D1ED4D-863B-45D7-9829-305DD33B4CE5} = {4E95C87B-655B-4BC3-8F2A-DF06B7AAB7E9}
{F3AA76EC-C7D8-42DA-947D-4376B6562772} = {4E95C87B-655B-4BC3-8F2A-DF06B7AAB7E9}
{782E4DC1-8186-4BAC-B2F4-89E6DF22A4DD} = {AAD39891-0B70-47FA-A212-43E1AAE5DF56}
+ {B1CA9165-89D9-4D6E-AFEF-5434A8D8A672} = {E622CFF2-C6C4-40FB-BE42-7C4F2B38B75A}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {573B2B5F-8CBB-4D52-A55A-4E65E282AAFB}
diff --git a/Elastic.OpenTelemetry.sln.DotSettings b/Elastic.OpenTelemetry.sln.DotSettings
index 5a02848..1a8f956 100644
--- a/Elastic.OpenTelemetry.sln.DotSettings
+++ b/Elastic.OpenTelemetry.sln.DotSettings
@@ -585,6 +585,7 @@ See the LICENSE file in the project root for more information
True
True
True
+ True
True
True
True
diff --git a/build/build.fsproj b/build/build.fsproj
index c4d18d0..40a5dc5 100644
--- a/build/build.fsproj
+++ b/build/build.fsproj
@@ -8,6 +8,7 @@
+
@@ -21,6 +22,7 @@
+
diff --git a/build/scripts/BuildInformation.fs b/build/scripts/BuildInformation.fs
index 6103337..e12988d 100644
--- a/build/scripts/BuildInformation.fs
+++ b/build/scripts/BuildInformation.fs
@@ -14,6 +14,7 @@ open Fake.Tools.Git
type BuildConfiguration =
static member ValidateAssemblyName = false
static member GenerateApiChanges = false
+ static member OpenTelemetryAutoInstrumentationVersion = SemVer.parse("1.7.0")
type Software =
static member Organization = "elastic"
diff --git a/build/scripts/CommandLine.fs b/build/scripts/CommandLine.fs
index 21fa4ce..e150787 100644
--- a/build/scripts/CommandLine.fs
+++ b/build/scripts/CommandLine.fs
@@ -34,6 +34,7 @@ type Build =
| [] ValidatePackages
| [] GenerateReleaseNotes
| [] GenerateApiChanges
+ | [] Redistribute
| [] Release
| [] Single_Target
@@ -63,6 +64,7 @@ with
| ValidateLicenses
| ValidatePackages
| GenerateReleaseNotes
+ | Redistribute
| GenerateApiChanges -> "Undocumented, dependent target"
// flags
diff --git a/build/scripts/Packaging.fs b/build/scripts/Packaging.fs
new file mode 100644
index 0000000..c76c662
--- /dev/null
+++ b/build/scripts/Packaging.fs
@@ -0,0 +1,111 @@
+// Licensed to Elasticsearch B.V under one or more agreements.
+// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information
+
+
+module Packaging
+
+open System
+open System.IO
+open System.IO.Compression
+open System.Net.Http
+open Argu
+open BuildInformation
+open CommandLine
+open Octokit
+
+let private otelAutoVersion = BuildConfiguration.OpenTelemetryAutoInstrumentationVersion;
+
+let private downloadFolder = Path.Combine(".artifacts", "otel-distribution", otelAutoVersion.AsString) |> Directory.CreateDirectory
+let private distroFolder = Path.Combine(".artifacts", "elastic-distribution", otelAutoVersion.AsString) |> Directory.CreateDirectory
+
+let private fileInfo (directory: DirectoryInfo) file = Path.Combine(directory.FullName, file) |> FileInfo
+let private downloadFile (asset: ReleaseAsset) = fileInfo downloadFolder asset.Name
+let private stageFile (asset: ReleaseAsset) = fileInfo downloadFolder (asset.Name.Replace("opentelemetry", "stage"))
+let private distroFile (asset: ReleaseAsset) = fileInfo distroFolder (asset.Name.Replace("opentelemetry", "elastic"))
+
+let pluginFiles tfm =
+ ["dll"; "pdb"; "xml"]
+ |> List.map(fun e -> $"Elastic.OpenTelemetry.%s{e}")
+ |> List.map(fun f -> Path.Combine(".artifacts", "bin", "Elastic.OpenTelemetry", $"release_%s{tfm}", "", f))
+ |> List.map(fun f -> FileInfo(f))
+
+
+/// downloads the artifacts if they don't already exist locally
+let downloadArtifacts (_:ParseResults) =
+ let client = GitHubClient(ProductHeaderValue("Elastic.OpenTelemetry"))
+ let token = Environment.GetEnvironmentVariable("GITHUB_TOKEN")
+ if not(String.IsNullOrWhiteSpace(token)) then
+ Console.WriteLine($"using GITHUB_TOKEN");
+ let tokenAuth = Credentials(token);
+ client.Credentials <- tokenAuth
+
+ let assets =
+ async {
+ let! release = client.Repository.Release.Get("open-telemetry", "opentelemetry-dotnet-instrumentation", $"v{otelAutoVersion.AsString}") |> Async.AwaitTask;
+ Console.WriteLine($"Release %s{release.Name} has %i{release.Assets.Count} assets");
+ return release.Assets
+ |> Seq.map (fun asset -> (asset, downloadFile asset))
+ |> Seq.toList
+ } |> Async.RunSynchronously
+
+ async {
+ use httpClient = new HttpClient()
+ assets
+ |> Seq.filter (fun (_, f) -> not f.Exists)
+ |> Seq.iter (fun (asset, f) ->
+ async {
+ Console.WriteLine($"Retrieving {asset.Name}");
+ let! fileData = httpClient.GetByteArrayAsync(asset.BrowserDownloadUrl) |> Async.AwaitTask
+ Console.WriteLine($"Saveing %i{fileData.Length} bytes to {f.FullName}")
+ File.WriteAllBytes(f.FullName, fileData)
+ f.Refresh()
+ } |> Async.RunSynchronously
+ )
+ } |> Async.RunSynchronously
+ assets
+
+let injectPluginFiles (asset: ReleaseAsset) (stagedZip: FileInfo) tfm target =
+ use zipArchive = ZipFile.Open(stagedZip.FullName, ZipArchiveMode.Update)
+ pluginFiles tfm |> List.iter(fun f ->
+ printfn $"Staging zip: %s{asset.Name}, Adding: %s{f.Name} (%s{tfm}_ to %s{target}"
+ zipArchive.CreateEntryFromFile(f.FullName, Path.Combine(target, f.Name)) |> ignore
+ )
+
+/// moves artifacts from open-distribution to elastic-distribution and renames them to `staged-dotnet-instrumentation*`.
+/// staged meaning we haven't injected our opentelemetry dll into the zip yet,
+let stageArtifacts (assets:List) =
+ let stagedZips =
+ assets
+ |> List.filter(fun (a, _) -> a.Name.EndsWith(".zip"))
+ |> List.map(fun (z, f) ->
+ let stage = stageFile z
+ z, f.CopyTo(stage.FullName, true)
+ )
+
+ stagedZips |> List.iter (fun (asset, path) ->
+
+ injectPluginFiles asset path "netstandard2.1" "net"
+ if asset.Name.EndsWith("-windows.zip") then
+ injectPluginFiles asset path "net462" "netfx"
+
+ let distro = distroFile asset
+ path.MoveTo(distro.FullName, true)
+ distro.Refresh()
+
+ printfn $"Created: %s{distro.FullName}"
+ )
+ stagedZips
+
+
+
+let redistribute (arguments:ParseResults) =
+ let assets = downloadArtifacts arguments
+ let staged = stageArtifacts assets
+
+ printfn ""
+ assets |> List.iter (fun (asset, path) ->
+ printfn "Asset: %s" asset.Name
+ )
+
+
diff --git a/build/scripts/Targets.fs b/build/scripts/Targets.fs
index 4f543f8..b70bba4 100644
--- a/build/scripts/Targets.fs
+++ b/build/scripts/Targets.fs
@@ -185,6 +185,7 @@ let Setup (parsed:ParseResults) =
| ValidatePackages -> Build.Step validatePackages
| GenerateReleaseNotes -> Build.Step generateReleaseNotes
| GenerateApiChanges -> Build.Step generateApiChanges
+ | Redistribute -> Build.Step Packaging.redistribute
// flags
| Single_Target
diff --git a/src/Elastic.OpenTelemetry.AutoInstrumentation/Elastic.OpenTelemetry.AutoInstrumentation.csproj b/src/Elastic.OpenTelemetry.AutoInstrumentation/Elastic.OpenTelemetry.AutoInstrumentation.csproj
new file mode 100644
index 0000000..db96356
--- /dev/null
+++ b/src/Elastic.OpenTelemetry.AutoInstrumentation/Elastic.OpenTelemetry.AutoInstrumentation.csproj
@@ -0,0 +1,52 @@
+
+
+
+ net6.0;net8.0;net462
+ enable
+ enable
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Elastic.OpenTelemetry.AutoInstrumentation/_instrument.cmd b/src/Elastic.OpenTelemetry.AutoInstrumentation/_instrument.cmd
new file mode 100755
index 0000000..9cf290b
--- /dev/null
+++ b/src/Elastic.OpenTelemetry.AutoInstrumentation/_instrument.cmd
@@ -0,0 +1,31 @@
+@echo off
+setlocal
+
+:: This script is expected to be used in a build that specified a RuntimeIdentifier (RID)
+set BASE_PATH=%~dp0
+
+:: Settings for .NET Framework
+set COR_ENABLE_PROFILING=1
+set COR_PROFILER={918728DD-259F-4A6A-AC2B-B85E1B658318}
+set COR_PROFILER_PATH=%BASE_PATH%OpenTelemetry.AutoInstrumentation.Native.dll
+
+:: On .NET Framework automatic assembly redirection MUST be disabled. This setting
+:: is ignored on .NET. This is necessary because the NuGet package doesn't bring
+:: the pre-defined versions of the transitive dependencies used in the automatic
+:: redirection. Instead the transitive dependencies versions are determined by
+:: the NuGet version resolution algorithm when building the application.
+set OTEL_DOTNET_AUTO_NETFX_REDIRECT_ENABLED=false
+
+:: Settings for .NET
+set ASPNETCORE_HOSTINGSTARTUPASSEMBLIES=OpenTelemetry.AutoInstrumentation.AspNetCoreBootstrapper
+set CORECLR_ENABLE_PROFILING=1
+set CORECLR_PROFILER={918728DD-259F-4A6A-AC2B-B85E1B658318}
+set CORECLR_PROFILER_PATH=%BASE_PATH%OpenTelemetry.AutoInstrumentation.Native.dll
+set DOTNET_STARTUP_HOOKS=%BASE_PATH%OpenTelemetry.AutoInstrumentation.StartupHook.dll
+
+:: Settings for OpenTelemetry
+set OTEL_DOTNET_AUTO_HOME=%BASE_PATH%
+set OTEL_DOTNET_AUTO_RULE_ENGINE_ENABLED=false
+
+@echo on
+%*
diff --git a/src/Elastic.OpenTelemetry.AutoInstrumentation/_instrument.sh b/src/Elastic.OpenTelemetry.AutoInstrumentation/_instrument.sh
new file mode 100755
index 0000000..1a8d131
--- /dev/null
+++ b/src/Elastic.OpenTelemetry.AutoInstrumentation/_instrument.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+BASE_PATH="$(cd "$(dirname "$0")" && pwd)"
+
+# Settings for .NET
+export ASPNETCORE_HOSTINGSTARTUPASSEMBLIES=OpenTelemetry.AutoInstrumentation.AspNetCoreBootstrapper
+export CORECLR_ENABLE_PROFILING=1
+export CORECLR_PROFILER="{918728DD-259F-4A6A-AC2B-B85E1B658318}"
+CORECLR_PROFILER_PATH="$(ls ${BASE_PATH}/OpenTelemetry.AutoInstrumentation.Native.*)"
+export CORECLR_PROFILER_PATH
+export DOTNET_STARTUP_HOOKS=${BASE_PATH}/OpenTelemetry.AutoInstrumentation.StartupHook.dll
+
+# Settings for OpenTelemetry
+export OTEL_DOTNET_AUTO_HOME=${BASE_PATH}
+export OTEL_DOTNET_AUTO_RULE_ENGINE_ENABLED=false
+
+exec "$@"
diff --git a/src/Elastic.OpenTelemetry.AutoInstrumentation/instrument.cmd b/src/Elastic.OpenTelemetry.AutoInstrumentation/instrument.cmd
new file mode 100644
index 0000000..4fbf084
--- /dev/null
+++ b/src/Elastic.OpenTelemetry.AutoInstrumentation/instrument.cmd
@@ -0,0 +1,9 @@
+@echo off
+setlocal
+
+:: This script is expected to be used in a build that specified a RuntimeIdentifier (RID)
+set BASE_PATH=%~dp0
+
+set OTEL_DOTNET_AUTO_PLUGINS=Elastic.OpenTelemetry.AutoInstrumentationPlugin, Elastic.OpenTelemetry
+
+call %BASE_PATH%_instrument.cmd %*
\ No newline at end of file
diff --git a/src/Elastic.OpenTelemetry.AutoInstrumentation/instrument.props b/src/Elastic.OpenTelemetry.AutoInstrumentation/instrument.props
new file mode 100644
index 0000000..c2e528f
--- /dev/null
+++ b/src/Elastic.OpenTelemetry.AutoInstrumentation/instrument.props
@@ -0,0 +1,12 @@
+
+
+
+
+
+ False
+ Always
+ Always
+
+
+
\ No newline at end of file
diff --git a/src/Elastic.OpenTelemetry.AutoInstrumentation/instrument.sh b/src/Elastic.OpenTelemetry.AutoInstrumentation/instrument.sh
new file mode 100644
index 0000000..720478e
--- /dev/null
+++ b/src/Elastic.OpenTelemetry.AutoInstrumentation/instrument.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+# This script is expected to be used in a build that specified a RuntimeIdentifier (RID)
+BASE_PATH="$(cd "$(dirname "$0")" && pwd)"
+
+export OTEL_DOTNET_AUTO_PLUGINS="Elastic.OpenTelemetry.AutoInstrumentationPlugin, Elastic.OpenTelemetry"
+
+. $BASE_PATH/_instrument.sh
+
+exec "$@"