Skip to content

Commit

Permalink
Improved .NET metrics support (#129)
Browse files Browse the repository at this point in the history
  • Loading branch information
cretz authored Aug 25, 2023
1 parent 5b559d5 commit 9d56fe8
Show file tree
Hide file tree
Showing 41 changed files with 1,589 additions and 202 deletions.
23 changes: 22 additions & 1 deletion src/Temporalio/Activities/ActivityExecutionContext.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using System.Threading;
using Google.Protobuf;
using Microsoft.Extensions.Logging;
using Temporalio.Common;
using Temporalio.Converters;

namespace Temporalio.Activities
Expand All @@ -13,6 +15,8 @@ namespace Temporalio.Activities
/// </summary>
public class ActivityExecutionContext
{
private readonly Lazy<IMetricMeter> metricMeter;

/// <summary>
/// Initializes a new instance of the <see cref="ActivityExecutionContext"/> class.
/// </summary>
Expand All @@ -22,21 +26,32 @@ public class ActivityExecutionContext
/// <param name="taskToken">Raw activity task token.</param>
/// <param name="logger">Logger.</param>
/// <param name="payloadConverter">Payload converter.</param>
/// <param name="runtimeMetricMeter">Runtime-level metric meter.</param>
#pragma warning disable CA1068 // We don't require cancellation token as last param
internal ActivityExecutionContext(
ActivityInfo info,
CancellationToken cancellationToken,
CancellationToken workerShutdownToken,
ByteString taskToken,
ILogger logger,
IPayloadConverter payloadConverter)
IPayloadConverter payloadConverter,
Lazy<IMetricMeter> runtimeMetricMeter)
{
Info = info;
CancellationToken = cancellationToken;
WorkerShutdownToken = workerShutdownToken;
TaskToken = taskToken;
Logger = logger;
PayloadConverter = payloadConverter;
metricMeter = new(() =>
{
return runtimeMetricMeter.Value.WithTags(new Dictionary<string, object>()
{
{ "namespace", info.WorkflowNamespace },
{ "task_queue", info.TaskQueue },
{ "activity_type", info.ActivityType },
});
});
}
#pragma warning restore CA1068

Expand Down Expand Up @@ -86,6 +101,12 @@ internal ActivityExecutionContext(
/// </summary>
public IPayloadConverter PayloadConverter { get; private init; }

/// <summary>
/// Gets the metric meter for this activity with activity-specific tags. Note, this is
/// lazily created for each activity execution.
/// </summary>
public IMetricMeter MetricMeter => metricMeter.Value;

/// <summary>
/// Gets the async local current value.
/// </summary>
Expand Down
149 changes: 131 additions & 18 deletions src/Temporalio/Bridge/Interop/Interop.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,27 @@

namespace Temporalio.Bridge.Interop
{
internal enum MetricAttributeValueType
{
String = 1,
Int,
Float,
Bool,
}

internal enum MetricIntegerKind
{
Counter = 1,
Histogram,
Gauge,
}

internal enum OpenTelemetryMetricTemporality
{
Cumulative = 1,
Delta,
}

internal enum RpcService
{
Workflow = 1,
Expand All @@ -23,6 +44,18 @@ internal partial struct EphemeralServer
{
}

internal partial struct MetricAttributes
{
}

internal partial struct MetricInteger
{
}

internal partial struct MetricMeter
{
}

internal partial struct Random
{
}
Expand Down Expand Up @@ -151,34 +184,59 @@ internal unsafe partial struct RpcCallOptions
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal unsafe delegate void ClientRpcCallCallback(void* user_data, [NativeTypeName("const struct ByteArray *")] ByteArray* success, [NativeTypeName("uint32_t")] uint status_code, [NativeTypeName("const struct ByteArray *")] ByteArray* failure_message, [NativeTypeName("const struct ByteArray *")] ByteArray* failure_details);

internal unsafe partial struct RuntimeOrFail
[StructLayout(LayoutKind.Explicit)]
internal partial struct MetricAttributeValue
{
[NativeTypeName("struct Runtime *")]
public Runtime* runtime;
[FieldOffset(0)]
[NativeTypeName("struct ByteArrayRef")]
public ByteArrayRef string_value;

[NativeTypeName("const struct ByteArray *")]
public ByteArray* fail;
[FieldOffset(0)]
[NativeTypeName("int64_t")]
public long int_value;

[FieldOffset(0)]
public double float_value;

[FieldOffset(0)]
[NativeTypeName("bool")]
public byte bool_value;
}

internal partial struct OpenTelemetryOptions
internal partial struct MetricAttribute
{
[NativeTypeName("struct ByteArrayRef")]
public ByteArrayRef url;
public ByteArrayRef key;

[NativeTypeName("struct ByteArrayRef")]
public ByteArrayRef headers;
[NativeTypeName("union MetricAttributeValue")]
public MetricAttributeValue value;

[NativeTypeName("uint32_t")]
public uint metric_periodicity_millis;
[NativeTypeName("enum MetricAttributeValueType")]
public MetricAttributeValueType value_type;
}

internal partial struct TracingOptions
internal partial struct MetricIntegerOptions
{
[NativeTypeName("struct ByteArrayRef")]
public ByteArrayRef filter;
public ByteArrayRef name;

[NativeTypeName("struct ByteArrayRef")]
public ByteArrayRef description;

[NativeTypeName("struct OpenTelemetryOptions")]
public OpenTelemetryOptions opentelemetry;
[NativeTypeName("struct ByteArrayRef")]
public ByteArrayRef unit;

[NativeTypeName("enum MetricIntegerKind")]
public MetricIntegerKind kind;
}

internal unsafe partial struct RuntimeOrFail
{
[NativeTypeName("struct Runtime *")]
public Runtime* runtime;

[NativeTypeName("const struct ByteArray *")]
public ByteArray* fail;
}

internal partial struct LoggingOptions
Expand All @@ -190,10 +248,31 @@ internal partial struct LoggingOptions
public byte forward;
}

internal partial struct OpenTelemetryOptions
{
[NativeTypeName("struct ByteArrayRef")]
public ByteArrayRef url;

[NativeTypeName("MetadataRef")]
public ByteArrayRef headers;

[NativeTypeName("uint32_t")]
public uint metric_periodicity_millis;

[NativeTypeName("enum OpenTelemetryMetricTemporality")]
public OpenTelemetryMetricTemporality metric_temporality;
}

internal partial struct PrometheusOptions
{
[NativeTypeName("struct ByteArrayRef")]
public ByteArrayRef bind_address;

[NativeTypeName("bool")]
public byte counters_total_suffix;

[NativeTypeName("bool")]
public byte unit_suffix;
}

internal unsafe partial struct MetricsOptions
Expand All @@ -203,13 +282,19 @@ internal unsafe partial struct MetricsOptions

[NativeTypeName("const struct PrometheusOptions *")]
public PrometheusOptions* prometheus;

[NativeTypeName("bool")]
public byte attach_service_name;

[NativeTypeName("MetadataRef")]
public ByteArrayRef global_tags;

[NativeTypeName("struct ByteArrayRef")]
public ByteArrayRef metric_prefix;
}

internal unsafe partial struct TelemetryOptions
{
[NativeTypeName("const struct TracingOptions *")]
public TracingOptions* tracing;

[NativeTypeName("const struct LoggingOptions *")]
public LoggingOptions* logging;

Expand Down Expand Up @@ -386,6 +471,34 @@ internal static unsafe partial class Methods
[DllImport("temporal_sdk_bridge", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void client_rpc_call([NativeTypeName("struct Client *")] Client* client, [NativeTypeName("const struct RpcCallOptions *")] RpcCallOptions* options, void* user_data, [NativeTypeName("ClientRpcCallCallback")] IntPtr callback);

[DllImport("temporal_sdk_bridge", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("struct MetricMeter *")]
public static extern MetricMeter* metric_meter_new([NativeTypeName("struct Runtime *")] Runtime* runtime);

[DllImport("temporal_sdk_bridge", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void metric_meter_free([NativeTypeName("struct MetricMeter *")] MetricMeter* meter);

[DllImport("temporal_sdk_bridge", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("struct MetricAttributes *")]
public static extern MetricAttributes* metric_attributes_new([NativeTypeName("const struct MetricMeter *")] MetricMeter* meter, [NativeTypeName("const struct MetricAttribute *")] MetricAttribute* attrs, [NativeTypeName("size_t")] UIntPtr size);

[DllImport("temporal_sdk_bridge", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("struct MetricAttributes *")]
public static extern MetricAttributes* metric_attributes_new_append([NativeTypeName("const struct MetricAttributes *")] MetricAttributes* orig, [NativeTypeName("const struct MetricAttribute *")] MetricAttribute* attrs, [NativeTypeName("size_t")] UIntPtr size);

[DllImport("temporal_sdk_bridge", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void metric_attributes_free([NativeTypeName("struct MetricAttributes *")] MetricAttributes* attrs);

[DllImport("temporal_sdk_bridge", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("struct MetricInteger *")]
public static extern MetricInteger* metric_integer_new([NativeTypeName("const struct MetricMeter *")] MetricMeter* meter, [NativeTypeName("const struct MetricIntegerOptions *")] MetricIntegerOptions* options);

[DllImport("temporal_sdk_bridge", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void metric_integer_free([NativeTypeName("struct MetricInteger *")] MetricInteger* metric);

[DllImport("temporal_sdk_bridge", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void metric_integer_record([NativeTypeName("const struct MetricInteger *")] MetricInteger* metric, [NativeTypeName("uint64_t")] ulong value, [NativeTypeName("const struct MetricAttributes *")] MetricAttributes* attrs);

[DllImport("temporal_sdk_bridge", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("struct Random *")]
public static extern Random* random_new([NativeTypeName("uint64_t")] ulong seed);
Expand Down
Loading

0 comments on commit 9d56fe8

Please sign in to comment.