Skip to content

Commit ee32ce6

Browse files
RohitRanjanMSjviauandystaplesgavin-aguiarAzureFunctionsPython
authored
[Flex] Adding support for OpenTelemetry (#10094)
* OpenTelemetry support (#9985) Adding support for OpenTelemetry --------- Co-authored-by: Jacob Viau <[email protected]> Co-authored-by: Shyju Krishnankutty <[email protected]> Co-authored-by: Daniel Castro <[email protected]> * Updating Otel nuget packages. (#10014) * Updating Otel nuget packages. * Update Azure.Identity to 1.11.2 (#10037) * Update Microsoft.Identity.Client to 4.60.3 * Update Azure.Identity to 1.11.2 * Remove Microsoft.Identity.Client * Update WebJobs package in test projects (#10061) * Update PowerShell workers to latest (#10016) * Update Python Worker Version to 4.28.0 (#10009) Co-authored-by: AzureFunctionsPython <[email protected]> * Update Node.js Worker to 3.10.0 (#9999) * Update Node.js Worker to 3.10.0 * Add PR reference * Update Python Worker Version to 4.28.1 (#10028) Co-authored-by: AzureFunctionsPython <[email protected]> --------- Co-authored-by: Jacob Viau <[email protected]> Co-authored-by: andystaples <[email protected]> Co-authored-by: gavin-aguiar <[email protected]> Co-authored-by: AzureFunctionsPython <[email protected]> Co-authored-by: Daniel Castro <[email protected]>
1 parent 018e67c commit ee32ce6

File tree

44 files changed

+1622
-114
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1622
-114
lines changed

build/python.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<Project>
22
<ItemGroup>
3-
<PackageReference Include="Microsoft.Azure.Functions.PythonWorker" Version="4.27.0" />
3+
<PackageReference Include="Microsoft.Azure.Functions.PythonWorker" Version="4.28.1" />
44
</ItemGroup>
55
</Project>

release_notes.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
<!-- Please add your release notes in the following format:
44
- My change description (#PR)
55
-->
6+
- Update Python Worker Version to [4.28.1](https://github.com/Azure/azure-functions-python-worker/releases/tag/4.28.1)
67
- DotnetIsolated worker artifact clean up (#9976)
78
- Move symbols from dotnet-isolated worker to symbols package
8-
- Removed linux executables from dotnet-isolated worker.
9+
- Removed linux executables from dotnet-isolated worker.
10+
- Update Azure.Identity to 1.11.0 (#10002)
11+
- Update PowerShell worker 7.2 to [4.0.3220](https://github.com/Azure/azure-functions-powershell-worker/releases/tag/v4.0.3220)
12+
- Update PowerShell worker 7.4 to [4.0.3219](https://github.com/Azure/azure-functions-powershell-worker/releases/tag/v4.0.3219)
13+
- Update Node.js Worker Version to [3.10.0](https://github.com/Azure/azure-functions-nodejs-worker/releases/tag/v3.10.0) (#9999)

src/WebJobs.Script.Grpc/Channel/GrpcWorkerChannel.cs

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
using Microsoft.Azure.WebJobs.Script.Config;
2121
using Microsoft.Azure.WebJobs.Script.Description;
2222
using Microsoft.Azure.WebJobs.Script.Diagnostics;
23+
using Microsoft.Azure.WebJobs.Script.Diagnostics.OpenTelemetry;
2324
using Microsoft.Azure.WebJobs.Script.Eventing;
2425
using Microsoft.Azure.WebJobs.Script.Extensions;
2526
using Microsoft.Azure.WebJobs.Script.Grpc.Eventing;
@@ -565,6 +566,12 @@ internal void ApplyCapabilities(IDictionary<string, string> capabilities, GrpcCa
565566
_isWorkerApplicationInsightsLoggingEnabled = true;
566567
}
567568

569+
if (bool.TryParse(_workerCapabilities.GetCapabilityState(RpcWorkerConstants.WorkerOpenTelemetryEnabled), out bool otelEnabled) &&
570+
otelEnabled)
571+
{
572+
ScriptHost.WorkerOpenTelemetryEnabled = true;
573+
}
574+
568575
// If http proxying is enabled, we need to get the proxying endpoint of this worker
569576
var httpUri = _workerCapabilities.GetCapabilityState(RpcWorkerConstants.HttpUri);
570577
if (!string.IsNullOrEmpty(httpUri))
@@ -1670,29 +1677,47 @@ private void AddSample<T>(List<T> samples, T sample)
16701677

16711678
private void AddAdditionalTraceContext(MapField<string, string> attributes, ScriptInvocationContext context)
16721679
{
1673-
// This is only applicable for AI agents running along side worker
1674-
if (_environment.IsApplicationInsightsAgentEnabled())
1680+
bool isOtelEnabled = _scriptHostOptions?.Value.TelemetryMode == TelemetryMode.OpenTelemetry;
1681+
bool isAIEnabled = _environment.IsApplicationInsightsAgentEnabled();
1682+
1683+
if (isOtelEnabled || isAIEnabled)
16751684
{
1676-
attributes[ScriptConstants.LogPropertyProcessIdKey] = Convert.ToString(_rpcWorkerProcess.Id);
16771685
if (context.FunctionMetadata.Properties.TryGetValue(ScriptConstants.LogPropertyHostInstanceIdKey, out var hostInstanceIdValue))
16781686
{
1679-
attributes[ScriptConstants.LogPropertyHostInstanceIdKey] = Convert.ToString(hostInstanceIdValue);
1680-
}
1681-
if (context.FunctionMetadata.Properties.TryGetValue(LogConstants.CategoryNameKey, out var categoryNameValue))
1682-
{
1683-
attributes[LogConstants.CategoryNameKey] = Convert.ToString(categoryNameValue);
1687+
string id = Convert.ToString(hostInstanceIdValue);
1688+
1689+
if (isOtelEnabled)
1690+
{
1691+
Activity.Current?.AddTag(ResourceSemanticConventions.FaaSInstance, id);
1692+
}
1693+
if (isAIEnabled)
1694+
{
1695+
attributes[ScriptConstants.LogPropertyHostInstanceIdKey] = id;
1696+
}
16841697
}
1685-
string sessionid = Activity.Current?.GetBaggageItem(ScriptConstants.LiveLogsSessionAIKey);
1686-
if (!string.IsNullOrEmpty(sessionid))
1698+
}
1699+
1700+
if (isAIEnabled)
1701+
{
1702+
attributes[ScriptConstants.LogPropertyProcessIdKey] = Convert.ToString(_rpcWorkerProcess.Id);
1703+
attributes[ScriptConstants.OperationNameKey] = context.FunctionMetadata.Name;
1704+
string sessionId = Activity.Current?.GetBaggageItem(ScriptConstants.LiveLogsSessionAIKey);
1705+
if (!string.IsNullOrEmpty(sessionId))
16871706
{
1688-
attributes[ScriptConstants.LiveLogsSessionAIKey] = sessionid;
1707+
attributes[ScriptConstants.LiveLogsSessionAIKey] = sessionId;
16891708
}
1690-
string operationName = context.FunctionMetadata.Name;
1691-
if (!string.IsNullOrEmpty(operationName))
1709+
1710+
if (context.FunctionMetadata.Properties.TryGetValue(LogConstants.CategoryNameKey, out var categoryNameValue))
16921711
{
1693-
attributes[ScriptConstants.OperationNameKey] = operationName;
1712+
attributes[LogConstants.CategoryNameKey] = Convert.ToString(categoryNameValue);
16941713
}
16951714
}
1715+
1716+
if (isOtelEnabled)
1717+
{
1718+
Activity.Current?.AddTag(ResourceSemanticConventions.FaaSName, context.FunctionMetadata.Name);
1719+
Activity.Current?.AddTag(ResourceSemanticConventions.FaaSTrigger, OpenTelemetryConstants.ResolveTriggerType(context.FunctionMetadata?.Trigger?.Type));
1720+
}
16961721
}
16971722

16981723
private sealed class ExecutingInvocation : IDisposable

src/WebJobs.Script.WebHost/Features/FunctionExecutionFeature.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33

44
using System;
55
using System.Collections.Generic;
6+
using System.Diagnostics;
67
using System.Threading;
78
using System.Threading.Tasks;
89
using Microsoft.AspNetCore.Http;
910
using Microsoft.Azure.WebJobs.Script.Description;
1011
using Microsoft.Azure.WebJobs.Script.Diagnostics;
12+
using Microsoft.Azure.WebJobs.Script.Diagnostics.OpenTelemetry;
1113
using Microsoft.Azure.WebJobs.Script.Extensions;
1214
using Microsoft.Azure.WebJobs.Script.Host;
1315
using Microsoft.Extensions.Logging;
@@ -58,6 +60,9 @@ public async Task ExecuteAsync(HttpRequest request, CancellationToken cancellati
5860
{
5961
coldStartData.Add("dispatchDuration", dispatchStopwatch.GetElapsedTime().TotalMilliseconds);
6062
}
63+
64+
// Add tag for cold start
65+
Activity.Current?.AddTag(ResourceSemanticConventions.FaaSColdStart, true);
6166
}
6267

6368
var sw = ValueStopwatch.StartNew();

src/WebJobs.Script.WebHost/Metrics/HostMetricsProvider.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using System.Linq;
99
using System.Threading;
1010
using Microsoft.Azure.WebJobs.Host.Executors;
11+
using Microsoft.Azure.WebJobs.Script.Diagnostics.OpenTelemetry;
1112
using Microsoft.Azure.WebJobs.Script.Metrics;
1213
using Microsoft.Extensions.DependencyInjection;
1314
using Microsoft.Extensions.Hosting;
@@ -60,7 +61,7 @@ public void Start()
6061
{
6162
listener.EnableMeasurementEvents(instrument);
6263

63-
var instanceIdTag = instrument.Meter.Tags.FirstOrDefault(t => t.Key == TelemetryAttributes.ServiceInstanceId);
64+
var instanceIdTag = instrument.Meter.Tags.FirstOrDefault(t => t.Key == ResourceSemanticConventions.ServiceInstanceId);
6465
InstanceId = instanceIdTag.Value?.ToString() ?? string.Empty;
6566
}
6667
};

src/WebJobs.Script.WebHost/WebJobs.Script.WebHost.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
</ItemGroup>
6363

6464
<ItemGroup>
65-
<PackageReference Include="Azure.Identity" Version="1.10.2" />
65+
<PackageReference Include="Azure.Identity" Version="1.11.2" />
6666
<PackageReference Include="Azure.Security.KeyVault.Secrets" Version="4.2.0" />
6767
<PackageReference Include="Microsoft.ApplicationInsights" Version="2.22.0" />
6868
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.22.0" />

src/WebJobs.Script.WebHost/WebJobsScriptHostService.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
using Microsoft.Extensions.Hosting;
2929
using Microsoft.Extensions.Logging;
3030
using Microsoft.Extensions.Options;
31+
using OpenTelemetry.Logs;
32+
using OpenTelemetry.Metrics;
33+
using OpenTelemetry.Trace;
3134
using static Microsoft.Azure.WebJobs.Script.EnvironmentSettingNames;
3235
using IApplicationLifetime = Microsoft.AspNetCore.Hosting.IApplicationLifetime;
3336

@@ -872,6 +875,7 @@ private async Task Orphan(IHost instance, CancellationToken cancellationToken =
872875
else
873876
{
874877
DisposeDependencyTrackingModule(instance);
878+
FlushOpenTelemetry(instance);
875879
instance.Dispose();
876880
_logger.LogDebug("ScriptHost disposed");
877881
}
@@ -958,6 +962,28 @@ public object GetService(Type serviceType)
958962
return Services?.GetService(serviceType);
959963
}
960964

965+
private void FlushOpenTelemetry(IHost host)
966+
{
967+
var logger = GetHostLogger(host);
968+
foreach (var meterProvider in host.Services.GetServices<MeterProvider>())
969+
{
970+
logger.LogDebug(@"Flushing {providerName} ...", meterProvider);
971+
meterProvider.ForceFlush();
972+
}
973+
974+
foreach (var tracerProvider in host.Services.GetServices<TracerProvider>())
975+
{
976+
logger.LogDebug(@"Flushing {providerName} ...", tracerProvider);
977+
tracerProvider.ForceFlush();
978+
}
979+
980+
foreach (var logProvider in host.Services.GetServices<ILoggerProvider>().Where(i => i is OpenTelemetryLoggerProvider))
981+
{
982+
logger.LogDebug(@"Disposing {providerName} ...", logProvider);
983+
logProvider.Dispose();
984+
}
985+
}
986+
961987
protected virtual void Dispose(bool disposing)
962988
{
963989
if (!_disposed)

src/WebJobs.Script/Config/ConfigurationSectionNames.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,6 @@ public static class ConfigurationSectionNames
2424
public const string Retry = "retry";
2525
public const string SequentialJobHostRestart = JobHost + ":sequentialRestart";
2626
public const string SendCanceledInvocationsToWorker = "sendCanceledInvocationsToWorker";
27+
public const string TelemetryMode = "telemetryMode";
2728
}
2829
}

src/WebJobs.Script/Config/ScriptJobHostOptions.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Collections.Immutable;
77
using System.Collections.ObjectModel;
88
using Microsoft.Azure.WebJobs.Script.Description;
9+
using Microsoft.Azure.WebJobs.Script.Diagnostics.OpenTelemetry;
910

1011
namespace Microsoft.Azure.WebJobs.Script
1112
{
@@ -42,7 +43,7 @@ public string RootScriptPath
4243
public string InstanceId { get; }
4344

4445
/// <summary>
45-
/// Gets or sets NugetFallBackPath
46+
/// Gets or sets NugetFallBackPath.
4647
/// </summary>
4748
public string NugetFallBackPath { get; set; }
4849

@@ -129,5 +130,10 @@ public string RootScriptPath
129130
/// invocation to the worker.
130131
/// </summary>
131132
public bool SendCanceledInvocationsToWorker { get; set; } = true;
133+
134+
/// <summary>
135+
/// Gets or sets the telemetry mode.
136+
/// </summary>
137+
internal TelemetryMode TelemetryMode { get; set; } = TelemetryMode.ApplicationInsights;
132138
}
133139
}

src/WebJobs.Script/Config/ScriptJobHostOptionsSetup.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the MIT License. See License.txt in the project root for license information.
33

44
using System;
5+
using Microsoft.Azure.WebJobs.Script.Diagnostics.OpenTelemetry;
56
using Microsoft.Extensions.Configuration;
67
using Microsoft.Extensions.Options;
78

@@ -73,6 +74,16 @@ public void Configure(ScriptJobHostOptions options)
7374
options.TestDataPath = webHostOptions.TestDataPath;
7475
options.IsFileSystemReadOnly = webHostOptions.IsFileSystemReadOnly;
7576
options.IsStandbyConfiguration = webHostOptions.IsStandbyConfiguration;
77+
78+
var telemetryModeSection = jobHostSection.GetSection(ConfigurationSectionNames.TelemetryMode);
79+
if (telemetryModeSection.Exists() && Enum.TryParse(telemetryModeSection.Value, true, out TelemetryMode telemetryMode))
80+
{
81+
options.TelemetryMode = telemetryMode;
82+
}
83+
else
84+
{
85+
options.TelemetryMode = TelemetryMode.ApplicationInsights;
86+
}
7687
}
7788

7889
private void ConfigureFunctionTimeout(ScriptJobHostOptions options)

0 commit comments

Comments
 (0)