如何手动读取jenkins中/ timestamps文件的内容

时间:2013-06-06 13:28:26

标签: jenkins

我正在尝试读取为构建生成的/ timestamps文件,但我无法理解文件格式,因为当我尝试打开它时包含一些特殊字符。我想将此文件用于脚本,该脚本将在构建完成后作为批处理命令运行。任何帮助,将不胜感激。感谢

3 个答案:

答案 0 :(得分:1)

依赖这样的插件的内部数据结构被认为是不好的做法 建议你联系该插件的作者,看看他是否可以为此提供一些API。

答案 1 :(得分:1)

如果您使用的是时间戳插件https://plugins.jenkins.io/timestamper/

您可以使用插件的API阅读日志。

http://${JENKINS_IP_PORT}/job/${JOB_NAME}/${JOB_NUMBER}/console

如果启用了插件,则返回带有时间戳的控制台视图,如果禁用,则不带时间戳。

http://${JENKINS_IP_PORT}/job/${JOB_NAME}/${JOB_NUMBER}/consoleText

将以纯文本格式返回日志


时间戳插件API

但是为该作业启用了插件后,您可以使用“脚本”部分下here可用的API。 响应为纯文本格式。

您可以设置返回日期,时间,日期+时间,经过时间(自作业开始以来的时间)等格式的时间戳。

示例

http://${JENKINS_IP_PORT}/job/${JOB_NAME}/${JOB_NUMBER}/timestamps/?time=yyyy-MM-dd%20HH:mm:ss&appendLog

2020-03-19 13:16:47  Jenkins did something here
2020-03-19 13:16:47  and this is something else that happend
2020-03-19 13:16:47  This line shows some output
2020-03-19 13:16:47  etc.
2020-03-19 13:16:47  etc.
2020-03-19 13:16:47  ...
2020-03-19 13:16:47  ...
2020-03-19 13:16:47
2020-03-19 13:16:47

返回时间戳并附加日志。日期格式为“ 2020-03-19 16:30:23”

使用M代替MM将返回不带前0的月份。

使用MMM会将月份返回为3个字母的月份,例如“ MAR”

http://${JENKINS_IP_PORT}/job/${JOB_NAME}/${JOB_NUMBER}/timestamps

2.667
2.670
2.768
32.778
32.778
32.820

将返回没有日志行的时间戳。自构建开始以来秒数的简单纯文本列表。

http://${JENKINS_IP_PORT}/job/${JOB_NAME}/${JOB_NUMBER}/timestamps/?time=yyyy-MM-dd%20HH:mm:ss

2020-03-19 13:16:47
2020-03-19 13:16:47
2020-03-19 13:16:47
2020-03-19 13:16:47
2020-03-19 13:16:47
2020-03-19 13:16:47
2020-03-19 13:16:47
2020-03-19 13:16:47
2020-03-19 13:16:47

将返回格式化的时间戳列表

警告

仅当作业启用了插件时,Timestamper API才可用。在其他情况下,访问API网址将返回一个空响应。

答案 2 :(得分:0)

六年后……我有同样的问题,无法找到答案。因此,我根据互联网上的花絮和自己的实验拼凑出了自己的解决方案。

我正在编写一个Web脚本来生成实时报告,并且它需要带有时间戳的Jenkins日志。我无法使用时间戳记URL / API,因为我的Web服务器禁止向其他Web服务器发送HTTP请求。因此,我需要能够直接从timestamps文件中提取时间戳信息,该文件可通过磁盘安装在服务器上使用。

请注意,我将Jenkins 2.190.1与Timestamper 1.10一起使用。您的里程可能会有所不同。

简要说明:

基本上,时间戳文件以毫秒为单位提供日志之间的经过时间。数据以base-128(varint)格式列出。因此,您需要一次读取一个字节的文件。如果任何字节大于0x7F(127),则需要取最低的7位,左移7位,然后读取下一个字节;否则,取0。重复直到读取的字节大于0x7F。

详细说明(包括Perl代码):

例如,给定以下字节(从实时时间戳文件的开头读取):

08 01 2c 04 0c 04 25 01 04 02 00 02 fe 47 11 ...

第一个字节0x08小于0x7f,因此第一个日志在构建开始后的8毫秒内发生。第二个字节0x01表示第二个日志在第一个日志之后1毫秒发生。第三条日志在第二条日志之后的0x2C ms(44ms)发生。依此类推。

第13个日志(字节0xfe)的情况有所不同。由于0xfe> 0x7f,我们只需要最低的7位。

0xfe & 0x7f = 1111 1110 & 0111 1111 == 0111 1110 = 0x7e == 126

然后将结果左移7位(即乘以128):

0x7e << 7 == 0x3f00 == 16128

然后,我们读取下一个字节(0x47),该字节小于0x7F,因此它是此(第13个)日志的最后一个字节。因此,我们只需将此值添加到上面的左移值即可:

0x3f00 + 0x47 = 0x3f47 = 16128 + 71 = 16199

因此,第13条日志发生在第12条日志之后的16199ms(或16.199s)。

对时间戳文件中的每个字节重复此过程。

这给出文件中每个日志之间的经过时间(以毫秒为单位)。要查找实际的纪元时间戳,请使用时间戳文件的最后修改时间,然后向后进行。然后以所需的日期/时间格式显示每个日志的时间。

Perl代码示例:

以下Perl函数有效(Perl 5.22)。它基于[https://github.com/danaj/BitStream/blob/master/lib/Data/BitStream/Code/Varint.pm][1]中的get_varint()函数,但是Varint.pm模块在我的服务器上不可用(要让IT人员安装它实际上要比我编写和使用它花费的时间长得多)。测试以下代码)。可能不漂亮,但是可以。

我希望这会有所帮助。

my @Timestamps = ();
my $path = "/full/path/to/timestamps";

if(open(TS, '<:raw', $path))
  {
   my($byte, $ok, $shift);
   my $elapsed = 0;
   my $ms = 0;

   while()
     {
      $ok = read(TS, $byte, 1);

      if(!defined($ok) || $ok <= 0)
        { last; }

      $byte = sprintf("%d", ord($byte));
      $shift = 7;
      $ms = $byte & 0x7F;

      while($byte > 127)
        {
         $ok = read(TS, $byte, 1);

         if(!defined($ok) || $ok <= 0)
           { last; }

         $byte = sprintf("%d", ord($byte));
         $ms |= ($byte & 0x7F) << $shift;
         $shift += 7;
        } # end while byte

      $elapsed += $ms;
      push(@Timestamps, $elapsed);
     } # end while 

   close(TS);
  } # end if open