我是elixel的新手,我试图找到类似Python的ContextManager的东西。
问题:
我有很多函数,我想在它们周围添加延迟指标。
现在我们有:
def method_1 do
...
end
def method_2 do
...
end
... more methods
我想:
def method_1 do
start = System.monotonic_time()
...
end = System.monotonic_time()
emit_metric(end-start)
end
def method_2 do
start = System.monotonic_time()
...
end = System.monotonic_time()
emit_metric(end-start)
end
... more methods
现在代码重复是个问题
start = System.monotonic_time()
...
end = System.monotonic_time()
emit_metric(end-start)
那么,在这种情况下,有什么更好的方法来避免代码重复呢?我喜欢python中的上下文管理器的想法。但是现在我确定了如何在Elixir中实现类似的功能,提前感谢你的帮助!
3条答案
按热度按时间zour9fqk1#
在Erlang/Elixir中,这是通过高阶函数来完成的,看看BEAM telemetry。它是一个Erlang和Elixir库/标准,用于收集度量和测试代码a-它被Pheonix、Ecto、cowboy和其他库广泛采用。特别是,你会对
:telemetry.span/3
函数感兴趣,因为它默认发出开始时间和持续时间度量:然后,在代码的其他部分中,侦听这些事件并将其记录/发送到APM:
ntjbwcob2#
我认为最接近python上下文管理器的是使用更高阶的函数,也就是把函数作为参数的函数。所以你可以这样做:
你可以这样使用它:
注意:在Python中,还有其他类似的示例,你可以使用上下文管理器,以类似的方式完成,就在我的头顶上:Django有一个用于事务的上下文管理器,但Ecto使用了一个更高阶的函数来处理同样的事情。
PS:要测量经过的时间,您可能需要使用
:timer.tc/1
:pgccezyw3#
实际上有一个非常漂亮的库,叫做Decorator,在这个库中,宏可以用来" Package "你的函数来做各种各样的事情。
在本例中,您可以编写一个装饰器模块(感谢telemetry示例中的@maciej-szlosarczyk):
您可以在
Application.start
定义中设置遥测侦听器:然后,在您想要测量函数调用的任何模块中,您可以像这样"修饰"函数:
虽然这个例子使用了遥测技术,但是您可以在装饰器定义中轻松地打印出时间差。