Continuous integration Jenkins控制台输出不实时
詹金斯是个新手,我有一个简单但烦人的问题。当我在Jenkins上运行job(Build)时,我触发ruby命令来执行我的测试脚本 问题是Jenkins并没有从控制台实时显示输出。这是触发日志Continuous integration Jenkins控制台输出不实时,continuous-integration,jenkins,Continuous Integration,Jenkins,詹金斯是个新手,我有一个简单但烦人的问题。当我在Jenkins上运行job(Build)时,我触发ruby命令来执行我的测试脚本 问题是Jenkins并没有从控制台实时显示输出。这是触发日志 Building in workspace /var/lib/jenkins/workspace/foo_bar No emails were triggered. [foo_bar] $ /bin/sh -xe /tmp/hudson4042436272524123595.sh + ruby /var/l
Building in workspace /var/lib/jenkins/workspace/foo_bar
No emails were triggered.
[foo_bar] $ /bin/sh -xe /tmp/hudson4042436272524123595.sh
+ ruby /var/lib/jenkins/test-script.rb
基本上,它挂起这个输出直到构建完成,而不是仅仅显示完整的输出。有趣的是,这不是一贯的行为,有时它的工作,因为它应该。但大多数情况下没有实时控制台输出
詹金斯版本:1.461操作系统本质上是在缓冲输出数据,以节省CPU,詹金斯也是如此 看起来您正在使用shell命令运行Ruby脚本-
我建议直接通过专用插件运行Ruby脚本:
(可能需要安装)确保脚本正在刷新其标准输出和标准输出。 在我的例子中,我遇到了一个与您描述的类似的缓冲问题,但我使用的是python。 下面的python代码为我修复了它: 导入系统 sys.stdout.flush() 我不是Ruby程序员,但Google透露了以下信息:
$stdout.flush
这里最简单的解决方案是打开将缓冲区同步到输出。@Craig在他的回答中提到了这一点,但一行解决方案将覆盖整个脚本,并且不需要多次刷新缓冲区
只要写
STDOUT.sync = true
后面的逻辑很简单,以避免在缓冲输出时多次使用IO操作。要禁用此功能,请执行以下操作:
STDOUT.sync = false
这是C的Ruby解决方案。在我看来,
python-u
也可以工作
例如,批处理命令
python -u foo.py
澄清一些答案
或ruby
或任何合理的脚本语言将缓冲输出;这是为了最小化IO;写入磁盘很慢,写入控制台很慢python
- 通常,在缓冲区中有足够的数据并对换行进行特殊处理后,数据会自动进行
。e、 g.在flush()
完成之前,如果不使用换行符编写字符串,那么sleep()
将不会写入任何内容(我仅使用sleep()
作为示例,请随意使用任何其他昂贵的系统调用进行替换)sleep
from time import sleep
def test():
print "ok",
time.sleep(3)
print "now",
time.sleep(5)
print "done"
time.sleep(5)
print "again"
test()
- 对于
,打开ruby
;所有写入autoflush
的操作后面都是STDOUT
。这将解决您的问题,但会导致更多IOflush()
STDOUT.sync = true
- 对于
,可以使用python
或环境变量python-u
使PYTHONUNBUFFERED
不被缓冲,但不会改变stdin/stdout/stout
或stdin
stderr
export PYTHONUNBUFFERED=1
- 对于
,您有perl
stdbuf
更改任何程序的缓冲行为
在我的例子中,我通过tee
和grep
将shell脚本的输出管道化,以便根据内容将行拆分为控制台或文件。控制台如OP所述悬挂。这解决了问题:
./slowly_parse.py login.csv |tee >(grep -v LOG: > out.csv) | stdbuf -oL -eL grep LOG:
最终我发现我可以将--行缓冲传递给grep,得到相同的结果:
./slowly_parse.py login.csv |tee >(grep -v LOG: > out.csv) | grep --line-buffered LOG:
其他答案是正确的,您需要确保标准输出没有缓冲
另一件需要注意的事情是Jenkins本身进行逐行缓冲。如果您有一个缓慢运行的进程,该进程会发出单个字符(例如,nunit测试套件摘要打印一个
,表示测试成功,打印一个E
,表示错误),那么在行尾之前,您将看不到任何内容
[适用于运行在Windows设备上的my Jenkins 1.572。]对于某些命令,包括tee
a,解除缓冲的最佳选择是从程序包调用的程序
用法示例:
而不是
somecommand | tee/some/path
做
somecommand | unbuffer-p tee/some/path
来源和更多信息:
Python缓冲了它的输出跟踪,并在脚本末尾打印它,以最大限度地减少控制台上的写入,因为写入控制台的速度很慢
您可以在跟踪后使用以下命令。它将把在该命令之前排队的所有跟踪刷新到控制台
sys.stdout.flush()
您正在运行的服务器功能有多强大?执行此脚本需要多长时间?对我来说,这听起来像是由于服务器过载造成的延迟。当我的詹金斯大师满负荷运转时,我也看到过类似的症状。谢谢你们的关注,这是有道理的。在本例中,我们讨论的是EC2实例small
,但它只是在运行进程。您可能需要更多吗?这取决于正在运行的作业数量,但是是的,如果您在一个小实例上同时运行的作业数量超过几个,我希望看到延迟。我有一个类似的问题,但是,该机器的规格过高,使用不足。在jenkins之外运行python脚本也可以像预期的那样实时工作。该作业调用一个python脚本,该脚本跟踪另一个进程的日志文件。日志文件实时更新,jenkins输出被分块转储,就好像它在等待填充缓冲区一样。嗨Craig,你是对的,缓冲输出是个问题。使用STDOUT.sync=true
解决了这个问题。我会尝试一下,这需要一些时间。谢谢。您好,这不起作用:(尝试了相同的结果。另外,由于ruby代码保存在Jenkins作业中,所以解决方案不太实用,因此版本升级更难。我同意该解决方案的“非源代码控制”性质——最好管理Jenkins之外的任何脚本
./slowly_parse.py login.csv |tee >(grep -v LOG: > out.csv) | grep --line-buffered LOG: