c# - 除非定义了新的侦听器或管道,否则不会在 EventListener 中使用 Dotnet EventCounter
问题描述
我们使用事件计数器来记录速率和计量指标,我们正在扩展IncrementingEventCounter
和PollingCounter
使用它们,如下所示:
public sealed class GaugeCounter : PollingCounter
{
public GaugeCounter(EventSource eventSource, string name,Func<double> metricProvider)
: base(name.NotWhiteSpace(),eventSource,metricProvider)
{}
}
public sealed class RateCounter : IncrementingEventCounter
{
public RateCounter(EventSource eventSource,string name)
: base(name.NotWhiteSpace(), eventSource)
{}
}
public sealed class MetricsNamespace
{
public MetricsNamespace(EventSource eventSource,string @namespace)
{
_eventSource = eventSource;
_namespace = @namespace.NotWhiteSpace();
}
public GaugeCounter CreateGaugeCounter(string name,Func<double> metricProvider) =>
new GaugeCounter(_eventSource,GetCounterName(name.NotWhiteSpace()),metricProvider);
public RateCounter CreateRateCounter(string name) =>
new RateCounter(_eventSource,GetCounterName(name.NotWhiteSpace()));
}
此外,我们实现了事件计数器侦听器,它实现了两个功能OnEventSourceCreated
,并OnEventWritten
在创建事件侦听器和编写事件时运行逻辑:
private void OnEventSourceCreated(object? sender,EventSourceCreatedEventArgs eventSourceCreatedEventArgs)
{
EnableEvents(
eventSourceCreatedEventArgs.EventSource,
EventLevel.LogAlways,
EventKeywords.None,
new Dictionary<string, string?> { { "EventCounterIntervalSec", _sampleInterval.TotalSeconds.ToString(CultureInfo.InvariantCulture) } });
}
private void OnEventWritten(object? sender,EventWrittenEventArgs eventWrittenEventArgs)
{
var eventPayload = (IDictionary<string, object>)eventWrittenEventArgs.Payload.NotNull()[0].NotNull();
var metric = Metric.Parse(eventPayload);
_metrics[$"{eventWrittenEventArgs.EventSource.Name}|{metric.Name}"] = metric.Value;
}
使用示例如下:
_hitRateCounter = metricsNamespace.CreateRateCounter(nameof(_hitRateCounter));
_hitRateCounter.Increment();
令人惊讶的是,当我们在构造函数中使用它时,代码工作正常,但是当函数中定义的计数器时,监听器没有消耗事件:
public class MyClass
{
public MyClass()
{
// working
_hitRateCounter = metricsNamespace.CreateRateCounter(nameof(_hitRateCounter));
_hitRateCounter.Increment();
}
public async Task func()
{
// not working
_hitRateCounter = metricsNamespace.CreateRateCounter(nameof(_hitRateCounter));
_hitRateCounter.Increment();
}
}
我很好奇使用事件计数器有一些限制吗?我们应该总是在构造函数中定义它们吗?或者一段时间后事件源没有轮询新的计数器?
编辑:
我想通了,我正在为任何会遇到同样问题的人进行编辑。Dotnet 和 counters 作为Events
&Event Source
收集和解析事件 [counters],但是第一次我们声明一个计数器时,有第 3 类初始化和调用CounterGroup
。此类负责从计数器中提取新事件。这项工作是在假设指标或计数器在程序开始时初始化并永远存在的情况下完成的。
因此,推荐的方法是在程序启动时创建一次指标(这里没有意外),如果您想在程序启动之外的某个时间创建和处理指标,请确保您至少创建启动时的一个计数器,他EventSource
是您正在收听的事件源
附加代码片段作为示例:
public class MyClass
{
public MyClass()
{
// dummy counter in order to initialize
metricsNamespace.CreateRateCounter(nameof(_hitRateCounter)).Dispose();
}
public async Task func()
{
// working
_hitRateCounter = metricsNamespace.CreateRateCounter(nameof(_hitRateCounter));
_hitRateCounter.Increment();
}
}
解决方案
推荐阅读
- python - 检查是否在信息框上单击了确定
- gcc - 编译 MIPS 以使用分支而不是跳转
- r - 创建数据框时出错:只有 0 可以与负下标混合
- primefaces - Primefaces 计划模型加载错误
- wamp - 我怎样才能保护我的 wamp/www/文件夹名称,以便没有人可以玩我网站的内容
- node.js - 为什么当我在其中调用函数时,我的 for 循环只通过一次?
- pycharm - ModuleNotFound:没有名为“imutils”的模块
- spring - 如何在 spring-boot Web 应用程序中将对象或数据从一个控制器传递到另一个控制器?
- java - 如何从 Firebase 更新 ListView
- syntax-error - 无法开始使用 Hello World Electron 应用示例