Javascript 使用Node.js子进程生成strace命令
因为我不满意,而且没有得到答案,所以我尝试另一种方法来跟踪已经运行的程序的输出。我基于这段代码,我试图做的只是检索已经在运行的程序的日志信息 Obs:要使用Javascript 使用Node.js子进程生成strace命令,javascript,node.js,linux,logging,child-process,Javascript,Node.js,Linux,Logging,Child Process,因为我不满意,而且没有得到答案,所以我尝试另一种方法来跟踪已经运行的程序的输出。我基于这段代码,我试图做的只是检索已经在运行的程序的日志信息 Obs:要使用strace而不使用sudo,您需要使用以下命令来允许它: echo kernel.yama.ptrace_scope = 0 > /etc/sysctl.d/10-ptrace.conf 可能只有在重新启动后它才能工作 这是我使用stracelinux命令和节点child\u进程的代码,其中-p1234是我们要跟踪的进程的编号
strace
而不使用sudo
,您需要使用以下命令来允许它:
echo kernel.yama.ptrace_scope = 0 > /etc/sysctl.d/10-ptrace.conf
可能只有在重新启动后它才能工作
这是我使用strace
linux命令和节点child\u进程的代码,其中-p1234
是我们要跟踪的进程的编号
import { spawn } from 'child_process';
const strace = spawn('strace', [ `-p1234`, '-s9999', '-e', 'write']);
strace.stdout.on('data', (data) => {
// I don't know why, but my output is not being returned here
console.log(`stdout: ${data}`);
});
strace.stderr.on('data', (data: any) => {
// 'data' output is something like: 'write(4, "my real log", 4) = 4\n',
// so we need to cleanup a little bit with regex.
const prefix = /^\write\(1, "/
const suffix = /", [0-9]\)?\s*=?\s?[0-9]?/
const raw = `${data}`.trim()
if (raw.match(prefix) && raw.match(suffix)) {
// cleaning msg
let log = raw.replace(prefix, '').trim().replace(suffix, '').trim();
if (!log.includes('\n')) {
// showing msg: "my real log"
console.log(log);
}
}
});
首先:我不知道为什么我的日志是在stderr
上输出的,而不是在stdout
上输出的,但好吧,我还是遵循编码
Second:如果我正在运行的程序输出日志速度很慢,就像一次打印一次一样,那么它的效果非常好
但是当我有一系列的2,3或4张照片时,它就不起作用了。我想,我花了太多的时间清理消息,所以当另一个<代码> Struts。StdRR.On()/<代码>到来时,我正处于进程的中间,一些问题发生了。在这种情况下,我只能看到序列的第一个打印。
我需要清理大量信息,因为消息是这样输出的:
'write(4, "9883", 4) = 4\n'
真是一团糟。我想也许一个只打印消息内容的命令也能解决我的问题
关于如何获得这些消息更一致的输出,有什么想法吗?正如我所说,我的唯一目的是检索另一个已经运行的程序输出的消息。我也试着遵循“登录文件并读取文件”的方法,但正如我所说的,我有一些问题
任何建议,改进,或完全不同的方法来实现这一目标将非常感谢 首先,我对手册页的阅读表明,stderr是该命令的默认值(在该页中查找--output
)
在data
事件中从strace获得的输出不能保证在换行边界上分割。当您的输出速度慢时,它正好可以正常工作。更快的输出将多行聚集在一起,并可能在非换行边界处分割行。要快速修复,请将stderr
管道连接到以下实例:
const rl=require('readline').createInterface({input:strace.stderr})
完成后,如果需要进一步帮助解析输出,可以使用更好的正则表达式一次解析整行:
rl.on('line',line=>{
常量re=/^write\((?\d+)、\s*、\s*(?:[^“]| \\”)、\s*(?\d+)\s*=\s*(?\d+)/
常数m=线匹配(re)
如果(m){
console.log(m.groups.data)
}
})
这将使用新命名的捕获组,因此如果您使用的是非常旧版本的node,请删除看起来像?
的部分,而不是m.groups.data
使用m[2]
这还假设strace输出中的双引号作为\“
,但我不知道实际情况是否如此。我不确定这是否能解决问题,但我可以建议将RxJS与fromEvent一起使用:@Cehhiro,你能更好地解释一下这将如何帮助我吗?”?谢谢天啊!我在这个问题上花了很多时间,而这个readline()
技巧起到了作用。非常感谢你这么好的解释!我不是正则表达式的专家,如果我想在Begging只接受write(1
,而不是所有的数字,我应该做什么更改?将正则表达式更改为/^write\(1,s*)(?(?:[^“]\124;\”)”),\ s*(?\d+)\s*=\s*(?\d+/
,因此您正在替换(?\d+)
与1
匹配,以匹配一个文字字符。\d
表示“任何数字,0-9”。