prometheus-net

Форк
0
/
GrpcRequestMiddlewareBase.cs 
98 строк · 3.4 Кб
1
using Grpc.AspNetCore.Server;
2
using Microsoft.AspNetCore.Http;
3

4
namespace Prometheus;
5

6
// Modeled after HttpRequestMiddlewareBase, just with gRPC specific functionality.
7
internal abstract class GrpcRequestMiddlewareBase<TCollector, TChild>
8
    where TCollector : class, ICollector<TChild>
9
    where TChild : class, ICollectorChild
10
{
11
    /// <summary>
12
    /// The set of labels from among the defaults that this metric supports.
13
    /// 
14
    /// This set will be automatically extended with labels for additional
15
    /// route parameters when creating the default metric instance.
16
    /// </summary>
17
    protected abstract string[] DefaultLabels { get; }
18

19
    /// <summary>
20
    /// Creates the default metric instance with the specified set of labels.
21
    /// Only used if the caller does not provide a custom metric instance in the options.
22
    /// </summary>
23
    protected abstract TCollector CreateMetricInstance(string[] labelNames);
24

25
    /// <summary>
26
    /// The factory to use for creating the default metric for this middleware.
27
    /// Not used if a custom metric is alreaedy provided in options.
28
    /// </summary>
29
    protected MetricFactory MetricFactory { get; }
30

31
    private readonly TCollector _metric;
32

33
    protected GrpcRequestMiddlewareBase(GrpcMetricsOptionsBase? options, TCollector? customMetric)
34
    {
35
        MetricFactory = Metrics.WithCustomRegistry(options?.Registry ?? Metrics.DefaultRegistry);
36

37
        if (customMetric != null)
38
        {
39
            _metric = customMetric;
40
            ValidateNoUnexpectedLabelNames();
41
        }
42
        else
43
        {
44
            _metric = CreateMetricInstance(DefaultLabels);
45
        }
46
    }
47

48
    protected TChild? CreateChild(HttpContext context)
49
    {
50
        var metadata = context.GetEndpoint()?.Metadata?.GetMetadata<GrpcMethodMetadata>();
51
        if (metadata == null)
52
        {
53
            // Not a gRPC request
54
            return null;
55
        }
56

57
        if (!_metric.LabelNames.Any())
58
        {
59
            return _metric.Unlabelled;
60
        }
61

62
        return CreateChild(context, metadata);
63
    }
64

65
    protected TChild CreateChild(HttpContext context, GrpcMethodMetadata metadata)
66
    {
67
        var labelValues = new string[_metric.LabelNames.Length];
68

69
        for (var i = 0; i < labelValues.Length; i++)
70
        {
71
            switch (_metric.LabelNames[i])
72
            {
73
                case GrpcRequestLabelNames.Service:
74
                    labelValues[i] = metadata.Method.ServiceName;
75
                    break;
76
                case GrpcRequestLabelNames.Method:
77
                    labelValues[i] = metadata.Method.Name;
78
                    break;
79
                default:
80
                    // Should never reach this point because we validate in ctor.
81
                    throw new NotSupportedException($"Unexpected label name on {_metric.Name}: {_metric.LabelNames[i]}");
82
            }
83
        }
84

85
        return _metric.WithLabels(labelValues);
86
    }
87

88
    /// <summary>
89
    /// If we use a custom metric, it should not have labels that are neither defaults nor additional route parameters.
90
    /// </summary>
91
    private void ValidateNoUnexpectedLabelNames()
92
    {
93
        var unexpected = _metric.LabelNames.Except(DefaultLabels);
94

95
        if (unexpected.Any())
96
            throw new ArgumentException($"Provided custom gRPC request metric instance for {GetType().Name} has some unexpected labels: {string.Join(", ", unexpected)}.");
97
    }
98
}

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.