Erlang:有没有比堆栈跟踪上的正则表达式更好的方法来判断堆栈上是否有东西?

发布于 12-04 13:29 字数 797 浏览 1 评论 0原文

我正在从事的项目有很多内置的遥测和调试机制,这些机制必须在发布时可用,但不得被系统的大多数部分使用。我想构建一个宏,在此类方法的顶部调用,如果未从非常有限的模块组之一调用该方法,则会抛出异常。

例如,我有一个调试模块,可用于从控制台操纵系统状态,并且我有一个 Web 工具,允许管理员检查和更改系统。一些专为其使用而设计的方法(但在整个系统的模块中实现)适合偶尔使用,但如果有人错误地在正常操作中调用它们,则会造成严重后果。

编辑:我已经尝试过下面的列表:keysearch 建议,它适用于我可以明确命名的任何模块,这可能是我要管理的最好的模块。我有像 web_foo、web_bar、web_foo_other、web_yippie_ki_yea_mf 这样的模块来匹配我依靠正则表达式。

我可以做如下的事情。 (我还没有编译这个。我希望您给出的任何答案都会阻止我将其投入生产。=]

try
  %gotta do this to get the stacktrace:
  throw(a)
catch
  _ -> 
    Stack = erlang:get_stacktrace(),
    {_, RegExp} = re:compile("webmanager", [multiline]),
    case Match = re:run(Stack, RegExp) of
      nomatch ->
        throw(im_sorry_dave__im_afraid_i_cant_do_that);
      {match, _} ->
        ok
    end
end

The project I'm working on has a lot of telemetry and debugging mechanisms built in that must be available in release, but MUST NOT be used by most parts of the system. I'd like to build a macro, to be called at the top of such methods, that would throw an exception if the method had not been called from one of a very limited group of modules.

For example, I have a debug module that I can use to manipulate system state from the console, and I have a web tool that allows admins to inspect and change the system. Some of the methods that are designed for their consumption (but are implemented in modules all over the system) are fine for occasional use, but would be crippling if someone made the mistake of calling them as part of normal operation.

EDIT: I've tried the lists:keysearch suggestion, below, and it works for any module that I can explicitly name, which is probably the best I'm ever going to manage. I have modules like web_foo, web_bar, web_foo_other, web_yippie_ki_yea_mf to match that I'm falling back on regexps for.

I can do something like the following. (I've not compiled this. I'm hoping that any answers you give will prevent me from ever putting this into production. =] )

try
  %gotta do this to get the stacktrace:
  throw(a)
catch
  _ -> 
    Stack = erlang:get_stacktrace(),
    {_, RegExp} = re:compile("webmanager", [multiline]),
    case Match = re:run(Stack, RegExp) of
      nomatch ->
        throw(im_sorry_dave__im_afraid_i_cant_do_that);
      {match, _} ->
        ok
    end
end

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

内心旳酸楚2024-12-11 13:29:37

由于 Stack 是表示方法调用的元组列表,因此您可以使用 lists:keysearch(webmanager, 1, Stack) 来检查模块是否在堆栈跟踪中。

Since Stack is a list of tuples representing the method calls, you can use lists:keysearch(webmanager, 1, Stack) to check if the module is in the stack trace.

情何以堪。2024-12-11 13:29:37

从您的描述中,我不明白为什么不将操作支持功能和调试功能隔离在不同的外观模块或进程后面。这些进程代码可以根据调用者的属性来限制调用者,例如注册名称(全局、本地、gproc)或节点名称。

-module(adm_facade).
-export([register_admin_mode_proc/0,
         unregister_admin_mode_proc/0,
         adm1/1
       ]).

register_admin_mode_proc() ->
    register(admin_mode_proc, self()).

unregister_admin_mode_proc() ->
    unregister(admin_mode_proc).

adm(X) ->
    check_adm(),
    some_other_module:adm(X).

check_adm() ->
    Caller = self(),
    case erlang:whereis(admin_mode_proc) of
        Caller -> ok;
        _ -> erlang:error({access_denied, Caller})
    end.

当然,这将管理功能限制为单个调用者,但您可以使用 gproc 或您自己的注册器。

From your description I can't see why not to isolate operations support functions and debugging ones behind different facade modules or processes. Those processes code could restrict callers based on their attributes, for example registered name (global, local, gproc) or node name.

-module(adm_facade).
-export([register_admin_mode_proc/0,
         unregister_admin_mode_proc/0,
         adm1/1
       ]).

register_admin_mode_proc() ->
    register(admin_mode_proc, self()).

unregister_admin_mode_proc() ->
    unregister(admin_mode_proc).

adm(X) ->
    check_adm(),
    some_other_module:adm(X).

check_adm() ->
    Caller = self(),
    case erlang:whereis(admin_mode_proc) of
        Caller -> ok;
        _ -> erlang:error({access_denied, Caller})
    end.

Of course this limits admin functions to a single caller, but you can use gproc or your own registrar.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文