黑客24小时在线接单的网站

黑客24小时在线接单的网站

我掌握了少数人才知道持续集成系统的日志密码

前言

前段时间用 Travis CI 发现它的部署日志包含了许多彩色日志。

而且我们知道这些可爱的颜色在使用命令行终端时也会出现。

当然,我不是不是为了吹它。它有实际效果,可以帮助我们快速定位问题!

我对此很好奇,Travis CI 如何将这些彩色日志转移到浏览器上?

我猜肯定不是通过识别关键词特征来做的,因为太 了low 了。

进行了查询后,查到了一个终于查到了关键词,它就是 ANSI escape sequences。

ANSI转义序列是控制终端和终端仿真器上光标位置、颜色等选项的标准。--维基百科

一般来说,在终端输出的彩色文本中包含一些转义序列字符,但我们看不到它们,并被终端分析。然后终端将这些字符分析成我们现在看到的彩色日志(包括一些颜色、下划线、粗体等)。

例如,我们在终端上npm 的安装,git 分支切换,包括操作报错时可见。

正是这些颜色大大提高了我们的调试效率,一眼就能看到哪些命令出了问题,如何解决。

我们现在要做的是如何将这些彩色日志输出到浏览器端。在这一步之前,我们必须知道这些ANSI转义序列的形式是什么?

根据wiki了解 ANSI 转义序列可以操作许多功能,如光标位置、颜色、下划线和其他选项。让我们解释一下 的颜色部分。

ANSI 转义序列

ANSI 转义序列 也随着终端的发展而发展,颜色规格也随着设备的不同而不同。例如,早期设备只支持 3 / 4 Bit ,支持的颜色是 8 / 16 。

ANSI 转义序列大多是 ESC 和‘开头嵌入文本,终端会找到并解释为命令,而不是字符串。

ESC 的 ANSI 为 27 ,8进制为 \033 ,16进制为 \u001B。

3/4 bit

原规格只有 8/16 色。

比如ESC[30;47m 它是以 ESC[ 开头 m 结束,中间是code码,按分号分割。

color 取值为30-37,background 取值为 40-47。例如 :

  • echo-e"\u001B[31mhello"
  • (如果你想去除颜色,你需要使用 ESC [39;49m(有些终端不支持) 或ESC[0m )

    后来终端增加了直接指定 90-97 和 100-107 的“明亮”颜色能力。

    效果如下:

    以下是其颜色对照表:

    8-bit

    后来,由于256种颜色在显卡上很常见,从预定义的256种颜色中添加了转义序列,即在原来的写作方法中添加了一个新的来代表更多的颜色。

  • ESC[38;5;<n>m//设置字体颜色
  • ESC[48;5;<n>m//设置背景色
  • 0-7:standardcolors(asinESC[30–37m)
  • 8-15:highintensitycolors(asinESC[90–97m)
  • 16-231:6×6×6cube(216colors):16 36×r 6×g b(0≤r,g,b≤5)
  • 232-255:grayscalefromblacktowhitein24steps
  • 例如:

  • echo-e"\u001B[38;5;11mhello"
  • 代表输出黄色字体。

  • echo-e"\u001B[48;5;14;38;5;13mhello"
  • 代表蓝色背景和粉色字体的输出。

    以下是其颜色对照表:

    24-bit

    未来的发展是支持 24 位真彩显卡,Xterm,KDE 的Konsole,以及所有的基础 libvte 终端(包括GNOME支持24位前景和背景色设置。

  • ESC[38;2;<r>;<g>;<b>m//前景色
  • ESC[48;2;<r>;<g>;<b>m//背景色
  • 例如:

  • echo-e"\u001B[38;2;100;228;75mhello"
  • 输出绿色字体代表 rgb(100,228,75)。

    解析工具

    在我们知道了转义的规范之后,我们需要 ANSI 分析字符。

    因为规范多,我们先调查一下 js 常用的色库,进行小探索。

    因为 3 / 4bit 兼容性更好,大多数工具(如chalk)会采用这 8 / 16 色来做高亮,因此我们先实现一个 8 / 16 色的解析。

    这里参考 ansiparse 这个分析库:

    核心思想如下:

  • constansiparse=require('ansiparse')
  • constansiStr="\u001B[34mHello\u001B[39mWorld\u001B[31m!\u001B[39m"
  • constjson=ansiparse(ansiStr)
  • console.log(json)
  • //json输出如下:
  • [
  • {foreground:'blue',text:'Hello'},
  • {text:'World'},
  • {foreground:'red',text:'!'}
  • ]
  • 然后我们可以写一个函数个函数来分析 JSON数组,输出 HTML。

  • functioncreateHtml(ansiList,wrap=''){
  • lethtml='';
  • for(leti=0;i<ansiList.length;i ){
  • consthtmlFrame=ansiList[i];
  • const{background='',text,foreground=''}=htmlFrame;
  • if(background&&foreground){
  • if(text.includes('\n')){
  • html =wrap;
  • continue;
  • }
  • html =fontBgCode(text,foreground,background);
  • continue;
  • }
  • if(background||foreground){
  • constcolor=background?`bg-${background}`:foreground;
  • lettextColor=bgCode(text,color);
  • textColor=textColor.replace(/\n/g,wrap);
  • html =textColor;
  • continue;
  • }
  • if(text.includes('\n')){
  • consttextColor=text.replace(/\n/g,wrap);
  • html =textColor;
  • continue;
  • }
  • html =singleCode(text);
  • }
  • html =''
  • returnhtml;
  • }
  • functionfontBgCode(value,color,bgColor){
  • return`<spanclass="${color}bg-${bgColor}">${value}</span>`
  • }
  • functionbgCode(value,color){
  • return`<spanclass="${color}">${value}</span>`
  • }
  • functionsingleCode(value){
  • return`<span>${value}</span>`
  • }
  • 使用示例如下:

  • conststr="\u001B[34mHello\u001B[39mWorld\u001B[31m!\u001B[39m";
  • console.log(createHtml(parseAnsi(str)));
  • //<spanclass="blue">Hello</span><span>World</span><spanclass="red">!</span>
  • 部署实战

    有了以上部分,我们将使用一个简单的部分demo实际演示部署日志吧!

  • ///项目录结构
  • demo
  • |-package.json
  • |-index.html
  • |-webpack.config.js
  • |-/src
  • |-index.js
  • index.js
  • build.sh
  • 我们在 index.js 中启动一个 build 脚本,模拟我们的真实部署场景。

  • const{spawn}=require('child_process');
  • constcmd=spawn('sh',['build.sh']);
  • cmd.stdout.on('data',(data)=>{
  • console.log(`stdout:${data}`);
  • });
  • cmd.stderr.on('data',(data)=>{
  • console.log(`stderr:${data}`);
  • });
  • cmd.on('close',(code)=>{
  • console.log(`childprocessexitedwithcode${code}`);
  • });
  • //build.sh
  • cddemo
  • npxwebpack
  • 我们试着在终端上输入控制台node index.js

    在输出日志中没有看到相应的颜色。

    为什么从 child_process 为什么我们不能输出颜色,如果我们直接在终端上打包项目,我们可以输出颜色?

    Why?

    第一反应是找到根源,即使用频率最高的颜色输出库。

    以简单的方式标记控制台输出的颜色。

    https://github.com/Marak/colors.js

    https://github.com/chalk/chalk

    在看了webpack-cli发现源码后,使用了它colorette作为色彩输出库。

    让我们来看看colorette探索源码。

    在入口文件的开头看到一个变量isColorSupported判断颜色输出是否支持。

    https://github.com/jorgebucaran/colorette/blob/main/index.js#L17

  • //colorette/index.js
  • import*asttyfrom"tty"
  • constenv=process.env||{}
  • constargv=process.argv||[]
  • constisDisabled="NO_COLOR"inenv||argv.includes("--no-color")
  • constisForced="FORCE_COLOR"inenv||argv.includes("--color")
  • constisWindows=process.platform==="win32"
  • constisCompatibleTerminal=tty&&tty.isatty&&tty.isatty(1)&&env.TERM&&env.TERM!=="dumb"
  • constisCI="CI"inenv&&("GITHUB_ACTIONS"inenv||"GITLAB_CI"inenv||"CIRCLECI"inenv)
  • exportconstisColorSupported=!isDisabled&&(isForced||isWindows||isCompatibleTerminal||isCI)
  • 可以看出,这种工具判断了很多条件来处理我们的输出流。

    只有建立上述条件,才能输出 ANSI 日志。在不符合上述条件的情况下,输出更容易分析。

    const isWindows = process.platform === "win32"

    参考:https://stackoverflow.com/questions/8683895/how-do-i-determine-the-current-operating-system-with-node-js

    dumb: "哑终端"

    哑终端不能执行,如“删行”、“清屏”或“控制光标位置”的一些特殊ANSI计算机终端计算机终端

    参考:https://zh.wikipedia.org/wiki/哑终端

    也就是说,我们的 child_process 的输出流关闭了终端模式(TTY),以上四种情况都不满意。所以我们得不到 ANSI 色彩日志。

    How?

    我们可以显示进入环境的变量 FORCE_COLOR=1 或命令带上参数 --color 强制启动颜色来解决这个问题。

    就这样,我们得到了带 的ANSI 颜色信息的输出文本,最终解析得到 HTML。

  • <div>asset<spanclass="green">main.js</span><span>132bytes</span><spanclass="yellow">[comparedforemit]</span><span></span><spanclass="green">[minimized]</span>(name:main)</div><div><span>./src/index.js</span><span>289bytes</span><spanclass="yellow">[built]</span><span></span><spanclass="yellow">[codegenerated]</span></div><div></div><div><spanclass="yellow">WARNING</span><span>in</span>configuration</div><div>The<spanclass="red">'mode'optionhasnotbeenset</span>,webpackwillfallbackto'production'forthisvalue.</div><div><spanclass="green">Set'mode'optionto'development'or'production'</span>toenabledefaultsforeachenvironment.</div><div>Youcanalsosetitto'none'todisableanydefaultbehavior.Learnmore:https://webpack.js.org/configuration/mode/</div><div></div><div>webpack5.53.0compiledwith<spanclass="yellow">1warning</span>in201ms</div><div></div>
  • 然后我们可以在浏览器中显示与终端输出一致的彩色输出日志。

    参考

    https://www.twilio.com/blog/guide-node-js-logging

    https://github.com/jorgebucaran/colorette/blob/main/index.js#L17

    https://en.wikipedia.org/wiki/ANSI_escape_code#Colors

    https://stackoverflow.com/questions/4842424/list-of-ansi-color-escape-sequences

    https://stackoverflow.com/questions/15011478/ansi-questions-x1b25h-and-x1be

    https://bluesock.org/~willg/dev/ansi.html

    https://www.cnblogs.com/gamesky/archive/2012/07/28/2613264.html

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   

    https://github.com/mmalecki/ansiparse

       
    • 评论列表:
    •  闹旅矫纵
       发布于 2022-06-12 21:32:03  回复该评论
    • tmlhttps://www.cnblogs.com/gamesky/archive/2012/07/28/2613264.html                                                                          
    •  寻妄时窥
       发布于 2022-06-13 01:31:45  回复该评论
    • -231:6×6×6cube(216colors):16 36×r 6×g b(0≤r,g,b≤5)232-255:grayscalefromblacktowhitein24steps例如:echo-e"\u001B[38;5;11mhello"代

    发表评论:

    Powered By

    Copyright Your WebSite.Some Rights Reserved.