如何在实时应用程序上检查 DETS?

How to examine DETS on a live application?

我是 Erlang 的新手,但我想知道是否有可能以某种方式附加到工作应用程序并检查它正在使用的 ETS 或 DETS。如果是,能否举个小例子?

谢谢!

有两种方法可以做到这一点,这两种方法可能有效也可能无效,具体取决于 Erlang 节点的启动方式:

  • 使用to_erl
  • 通过 Erlang 分发
  • 打开远程 shell (erl -remsh)

无论哪种方式,您最终都会得到一个 Erlang shell,您可以在其中检查您的 tables。


run_erl 和 to_erl

如果 Erlang 节点是使用 run_erl 包装器启动的,那么您可以使用 to_erl 连接到 运行 节点。可以看到运行使用的run_erl命令:

ps -C run_erl -fww

例如,如果使用此命令启动 Erlang 节点:

run_erl -daemon /my/erlang/node/tmp/ /my/erlang/node/log/ /my/erlang/node/start

那么命令中的三个路径分别对应:

  1. 保存命名管道的目录
  2. 记录标准输出的目录
  3. 实际启动Erlang节点的命令

您想要第一个用于 to_erl,因此命令为:

to_erl /my/erlang/node/tmp/

注意结尾的斜杠! to_erl 如果缺少它会感到困惑。

要退出,请键入 Ctrl-D


使用 Erlang 分发连接

如果Erlang节点运行作为分布式节点,并且你知道秘密"cookie",你可以启动另一个节点并打开一个远程shell.

哪个节点名?长还是短?

您需要知道 运行 节点的节点名称,以及它是 运行 "long" 还是 "short" 节点名称。

在"long"节点名中,主机部分是完全限定的域名或IP地址,但在"short"节点名中,主机部分只是主机名,没有点。如果 Erlang 节点以 -name 选项启动,则它使用长节点名称,如果它以 -sname 选项启动,则使用短节点名称。如果这两个选项都没有使用,则它不是分布式节点并且无法连接到它。1

主机名在命令中可能是显式的也可能是隐式的。如果命令看起来像其中之一,则您已经知道确切的节点名称:

erl -name myerlangnode@mymachine.example.com
erl -sname myerlangnode@mymachine

但是如果 -name-sname 选项仅指定 "bare" 节点名称,您需要弄清楚它选择的开头主机名:

erl -name myerlangnode    # node name is actually myerlangnode@mymachine.example.com
erl -sname myerlangnode   # node name is actually myerlangnode@mymachine

什么是 cookie?

当一个 Erlang 节点连接到另一个时,两个节点需要具有相同的 "cookie" 配置,否则握手将失败。 cookie 可以从 Erlang 节点 运行 用户的主目录中的文件 .erlang.cookie 中读取,或者在启动节点时使用 -setcookie 命令明确设置。

让我们连接起来!

所以现在我们知道:

  • 运行 节点使用的确切节点名称
  • 节点是从 -name 还是 -sname 开始的(即长节点名还是短节点名)
  • cookie 是从用户的主目录读取还是用 -setcookie
  • 设置

现在我们可以连接了!我们需要启动一个临时的 Erlang 节点:

  • 使用 -name-sname,根据 运行 节点的启动方式
  • 使用唯一的节点名称
  • 要么使用与 运行 节点相同的 -setcookie 选项,要么以同一用户运行以访问相同的 .erlang.cookie 文件
  • 使用 -remsh ("remote shell") 连接到 运行 节点。
  • 使用 -hidden 避免被视为 Erlang 集群的一部分

所以像这样:

erl -hidden -name mytmpnode -setcookie secret -remsh myerlangnode@mymachine.example.com
erl -hidden -sname mytmpnode -setcookie secret -remsh myerlangnode@mymachine

这应该在 运行 节点上打开一个 shell。您可以通过查看提示来判断,它应该告诉您节点名称:

(myerlangnode@mymachine)1>

如果没有显示正确的节点名称,请参阅问题

要退出,请输入 Ctrl-g,然后输入 q


检查 ETS 或 DETS tables

一旦你有了 Erlang shell,你就可以检查 tables。使用 ets:all()dets:all() 列出现有的 table。对于 ETS,您可以使用 ets:tab2list,它显示 table:

中的所有条目
ets:tab2list(my_table).

对于 DETS,您可以使用 dets:match_object'_' 通配符模式:

dets:match_object(my_table, '_').

1 除非节点作为非分布式节点启动,后来变成分布式节点 net_kernel:start

如果您有权访问 Observer,则可以使用它来查看 ETS 表。从 erlang shell 只需键入 observer:start(). 即可打开 GUI。

要连接到 运行 命名节点,您可以使用 Erlang Shell 中的连接到远程节点选项。

启动命名节点

$erl -name application@hostname

从不同的机器或终端启动一个新的 erlang shell

$erl -name temp@hostname

从您的临时 erlang shell 通过按 Ctrl+g 连接到应用程序,然后按 h? 以获取选项列表。选项 r 连接到远程节点,c 连接到新作业。

>r 'application@hostname'
>c

之后您可以调用任何命令,就好像您在那台机器上调用任何命令一样 module:functions,然后访问 ETS 表。

如果你在同一台机器上没有别的,如果你在不同的机器上你必须设置cookies使它们匹配,否则你将无法连接。

断开连接时要小心,退出前必须切换到本地节点,或者杀死临时应用程序,不要杀死真正的应用程序。

Rebar3

如今很多人使用 Rebar3 创建和 运行 Erlang 项目,如果您不这样做,我强烈建议您使用它。

使用 Rebar3,您可以使用启动命令启动应用程序,并使用附加命令附加到 运行 应用程序。您必须使用 Rebar3 发布版本才能使用这些命令。 More info here.

样本:

rel/my_app/bin/my_app start
rel/my_app/bin/my_app attach

之后按照上面提到的方式访问 ETS 或使用 erlang man pages.

中列出的任何 ets 命令

使用 ctrl+D 分离。

混搭 您可以使用常规 erl -name temp@hostname shell 连接到以 rebar3 启动的项目。只要 cookie 匹配并且您知道节点名称,您就不必使用 Rebar3 附加到 运行 应用程序。