public EventuousMetrics()
    {
        _meter = EventuousDiagnostics.GetMeter(MeterName);

        var eventStoreMetric = _meter.CreateHistogram <double>(
            Constants.Components.EventStore,
            "ms",
            "Event store operation duration, milliseconds"
            );

        var appServiceMetric = _meter.CreateHistogram <double>(
            Constants.Components.AppService,
            "ms",
            "Application service operation duration, milliseconds"
            );

        _listener = new ActivityListener {
            ShouldListenTo  = x => x.Name == EventuousDiagnostics.InstrumentationName,
            Sample          = (ref ActivityCreationOptions <ActivityContext> _) => ActivitySamplingResult.AllData,
            ActivityStopped = Record
        };

        ActivitySource.AddActivityListener(_listener);

        void Record(Activity activity)
        {
            var dot = activity.OperationName.IndexOf('.');

            if (dot == -1)
            {
                return;
            }

            var prefix = activity.OperationName[..dot];
Exemple #2
0
 /// <summary>
 /// Adds Eventuous activity source to OpenTelemetry trace collection
 /// </summary>
 /// <param name="builder"><seealso cref="TracerProviderBuilder"/> instance</param>
 /// <returns></returns>
 public static TracerProviderBuilder AddEventuousTracing(this TracerProviderBuilder builder)
 {
     // The DummyListener is added by default so the remote context is propagated regardless.
     // After adding the activity source to OpenTelemetry we don't need the dummy listener.
     EventuousDiagnostics.RemoveDummyListener();
     return(Ensure.NotNull(builder)
            .AddSource(EventuousDiagnostics.InstrumentationName));
 }
Exemple #3
0
    public ConnectorApplicationBuilder <TSourceConfig, TTargetConfig> AddOpenTelemetry(
        Action <TracerProviderBuilder, Action <Activity, string, object> >?configureTracing = null,
        Action <MeterProviderBuilder>?configureMetrics = null,
        Sampler?sampler = null,
        ExporterMappings <TracerProviderBuilder>?tracingExporters = null,
        ExporterMappings <MeterProviderBuilder>?metricsExporters  = null
        )
    {
        _otelAdded = true;

        if (!Config.Connector.Diagnostics.Enabled)
        {
            return(this);
        }

        EventuousDiagnostics.AddDefaultTag(ConnectorIdTag, Config.Connector.ConnectorId);

        if (Config.Connector.Diagnostics.Tracing is { Enabled : true })
Exemple #4
0
    public SubscriptionMetrics(IEnumerable <GetSubscriptionGap> measures)
    {
        _meter = EventuousDiagnostics.GetMeter(MeterName);
        var getGaps = measures.ToArray();

        _checkpointMetrics = new Lazy <CheckpointCommitMetrics>(() => new CheckpointCommitMetrics());
        IEnumerable <SubscriptionGap>?gaps = null;

        _meter.CreateObservableGauge(
            GapCountMetricName,
            () => TryObserving(GapCountMetricName, () => ObserveGapValues(getGaps)),
            "events",
            "Gap between the last processed event and the stream tail"
            );

        _meter.CreateObservableGauge(
            GapTimeMetricName,
            () => TryObserving(GapTimeMetricName, ObserveTimeValues),
            "s",
            "Subscription time lag, seconds"
            );

        _meter.CreateObservableGauge(
            CheckpointQueueLength,
            () => TryObserving(CheckpointQueueLength, _checkpointMetrics.Value.Record),
            "events",
            "Number of pending checkpoints"
            );

        var histogram  = _meter.CreateHistogram <double>(ProcessingRateName, "ms", "Processing duration, milliseconds");
        var errorCount = _meter.CreateCounter <long>(ErrorCountName, "events", "Number of event processing failures");

        _listener = new ActivityListener {
            ShouldListenTo  = x => x.Name == EventuousDiagnostics.InstrumentationName,
            Sample          = (ref ActivityCreationOptions <ActivityContext> _) => ActivitySamplingResult.AllData,
            ActivityStopped = x => ActivityStopped(histogram, errorCount, x)
        };

        ActivitySource.AddActivityListener(_listener);

        IEnumerable <Measurement <double> > ObserveTimeValues()
        => gaps?
        .Select(x => Measure(x.TimeGap.TotalSeconds, x.SubscriptionId))
        ?? Array.Empty <Measurement <double> >();

        IEnumerable <Measurement <long> > ObserveGapValues(GetSubscriptionGap[] gapMeasure)
        => gapMeasure
        .Select(GetGap)
        .Where(x => x != SubscriptionGap.Invalid)
        .Select(x => Measure((long)x.PositionGap, x.SubscriptionId));

        Measurement <T> Measure <T>(T value, string subscriptionId) where T : struct
        {
            if (_customTags.Length == 0)
            {
                return(new Measurement <T>(value, SubTag(subscriptionId)));
            }

            var tags = new List <KeyValuePair <string, object?> >(_customTags)
            {
                SubTag(subscriptionId)
            };

            return(new Measurement <T>(value, tags));
        }
    }