谈谈在incubator-dolphinscheduler 中为啥不能及时看到python任务输出的print日志
一、incubator-dolphinscheduler 中如何获取shell类型的节点或者python类型的节点任务的日志
1、在org.apache.dolphinscheduler.server.worker.task.AbstractCommandExecutor 类中通过java.lang.ProcessBuilder 来将python 脚本生成命令进行执行,AbstractCommandExecutor中的部分源码如下:
......
} else {
//init process builder
ProcessBuilder processBuilder = new ProcessBuilder();
// setting up a working directory
processBuilder.directory(new File(taskExecutionContext.getExecutePath()));
// merge error information to standard output stream
processBuilder.redirectErrorStream(true); // setting up user to run commands
command.add("sudo");
command.add("-u");
command.add(taskExecutionContext.getTenantCode());
command.add(commandInterpreter());
command.addAll(commandOptions());
command.add(commandFile); // setting commands
processBuilder.command(command);
process = processBuilder.start();
}
......
2、通过process.getInputStream() 来获取命令终端输出的日志,部分源码如下:
private void parseProcessOutput(Process process) {
String threadLoggerInfoName = String.format(LoggerUtils.TASK_LOGGER_THREAD_NAME + "-%s", taskExecutionContext.getTaskAppId());
ExecutorService parseProcessOutputExecutorService = ThreadUtils.newDaemonSingleThreadExecutor(threadLoggerInfoName);
parseProcessOutputExecutorService.submit(new Runnable() {
@Override
public void run() {
BufferedReader inReader = null;
try {
inReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
long lastFlushTime = System.currentTimeMillis();
logBuffer.add("welcome to use bigdata scheduling system...");
Thread.sleep(Constants.DEFAULT_LOG_FLUSH_INTERVAL * 2);
while ((line = inReader.readLine()) != null || logBuffer.size()>0) {
if(null != line){
logBuffer.add(line);
}
lastFlushTime = flush(lastFlushTime);
}
if (logBuffer.size() > 0) {
Thread.sleep(Constants.DEFAULT_LOG_FLUSH_INTERVAL * 2);
lastFlushTime = flush(lastFlushTime);
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
} finally {
clear();
close(inReader);
}
}
});
parseProcessOutputExecutorService.shutdown();
}
二、 Python 脚本中通过print()打印输出的日志为啥不能及时被incubator-dolphinscheduler获取到以及如何改进python脚本任务
在python 脚本中,很多人习惯于用print()来输出日志,这本身也没啥问题,而且在python 3版本中,print()本身也是自动换行输出的,而dolphinscheduler 也是按行来读取process的输出的,按理应该是可以及时输出的。
if __name__=='__main__':
.........
print(xxxxxxxx)
.........
print(xxxxxxxx)
.........
print(xxxxxxxx)
在 Python 3中打印日志调用 print (obj) 的时候,事实上是调用了 sys.stdout.write(obj+'\n'),print ()将需要的打印内容打印到了控制台,然后追加了一个换行符,print() 会调用 sys.stdout 的 write() 方法。
一行print("hello,world") 其实等价于执行sys.stdout.write('hello,world'+'\n'),看到这里是不是就容易理解了。因为这样会一直写如到了缓冲区,需要等到线程退出等情况下,缓冲区的内容才会被刷出,但是我们可以通过在脚本中强制调用sys.stdout.flush() 让其及时的刷出。
三、 直接通过参数解决

python中提供了-u 参数:force the stdout and stderr streams to be unbuffered;this option has no effect on stdin; also PYTHONUNBUFFERED=x 可以强制输出e stdout and stderr streams
谈谈在incubator-dolphinscheduler 中为啥不能及时看到python任务输出的print日志的更多相关文章
- 谈谈我对Java中CallBack的理解
谈谈我对Java中CallBack的理解 http://www.cnblogs.com/codingmyworld/archive/2011/07/22/2113514.html CallBack是回 ...
- 访何红辉:谈谈Android源码中的设计模式
最近Android 6.0版本的源代码开放下载,刚好分析Android源码的技术书籍<Android源码设计模式解析与实战>上市,我们邀请到它的作者何红辉,来谈谈Android源码中的设计 ...
- [转]谈谈关于MVP模式中V-P交互问题
在差不多两年的时间内,我们项目组几十来号人都扑在一个项目上面.这是一个基于微软SCSF(Smart Client Software Factory)的项目,客户端是墨尔本一家事业单位.前两周,我奉命负 ...
- [转载]有些shell文件中为啥要用$(cd “$(dirname $0)“; pwd),pwd它不香吗
$(cd "$(dirname "$0")",pwd) 解析 xx.sh 文件内容如下: #!/bin/bash BIN_FOLDER=$(cd " ...
- 在java中为啥要重写toString 方法?
在java中为啥要重写toString 方法?下面以一个简单的例子来说明. 先定义一个test5类.并写它的get,set方法. package test5; public class Test5 { ...
- ASP.NET Core 中文文档 第三章 原理(8)日志
原文:Logging 作者:Steve Smith 翻译:刘怡(AlexLEWIS) 校对:何镇汐.许登洋(Seay) ASP.NET Core 内建支持日志,也允许开发人员轻松切换为他们想用的其他日 ...
- YbSoftwareFactory 代码生成插件【二十五】:Razor视图中以全局方式调用后台方法输出页面代码的三种方法
上一篇介绍了 MVC中实现动态自定义路由 的实现,本篇将介绍Razor视图中以全局方式调用后台方法输出页面代码的三种方法. 框架最新的升级实现了一个页面部件功能,其实就是通过后台方法查询数据库内容,把 ...
- 笔试题&面试题:找出一个数组中第m小的值并输出
题目:找出一个数组中第m小的值并输出. 代码: #include <stdio.h> int findm_min(int a[], int n, int m) //n代表数组长度,m代表找 ...
- C:函数:功能:实现字符数组中所有字母的倒序存放并输出
前两天小测碰到一道题,建立一个函数,功能:实现字符数组中所有字母的倒序存放并输出,一开始觉得简单跟数字数组差不多,运行一下发现很多格式错误,这些是不必要的错误,现在就来说下,先说一下代码思路:定义一个 ...
- c语言文件中关于while(!feof(fp)) 循环多输出一次的问题
文件中关于while(!feof(fp)) 循环多输出一次的问题 feof(fp)有两个返回值:如果遇到文件结束,函数feof(fp)的值为1,否则为0. 当读到文件末尾时,文件指针并没有 ...
随机推荐
- DotLiquid(.net模版引擎)
可用生成C#代码,在KSFramework中有使用:https://github.com/mr-kelly/KSFramework 主页:http://dotliquidmarkup.org/ 文档: ...
- python2和python3的版本历史及入门书籍
python版本历史 我们端游项目使用是python2.7版本 32位 python2 2.7.18 last version on 2020.4.20 2.7 first version on 20 ...
- vim 从嫌弃到依赖(13)——motion 进阶
在最开始的时候我们介绍了一些vim中的motion 包括如何在字符间.单词间.行间以及多行间移动.·但是motion中的内容可远不止我们介绍的这些,平时用到的也远不止之间介绍的那些. 之所以没有一次介 ...
- 深入浅出Java多线程(一):进程与线程
引言 大家好,我是你们的老伙计秀才. 在计算机系统的发展历程中,早期的计算机操作模式十分单一和低效.用户只能逐条输入指令,而计算机则按照接收指令的顺序逐一执行,一旦用户停止输入或进行思考,计算机会处于 ...
- 从嘉手札<2024-1-10.2>
我们每个人都是在受挫中成长起来的 你不能剥夺他人在受苦中获益的权利 大部分人对吃苦的含义可能理解的太肤浅了 穷并不是吃苦 吃苦的本质是长时间为了某个目标而聚焦的能力 在这个过程中放弃娱乐生活.放弃无效 ...
- 解决github无法进入问题,DNS加速
1.电脑的hosts文件在下面这个地址,找到hosts文件 C:\Windows\System32\Drivers\etc 2.进入文件夹目录etc 找到hosts文件,使用记事本编辑 3.进入这个网 ...
- [XXL-JOB] 项目集成-Framework
1.导入pom坐标 <dependency> <groupId>com.hbasesoft.framework</groupId> <artifactId&g ...
- nginx入门之安装和启动
1.安装环境 nginx 使用源码编译安装,环境及组件如下: make 环境 openssl-fips-2.0.10 pcre-8.44 zlib-1.2.11 nginx-1.10.2 需要注意各组 ...
- Visual Studio 2022 企业版 离线包 下载
今天安装了Visual Studio 2022 企业版工具,觉得改进还是有一定的,下面提供下载及序列号: 链接:https://pan.baidu.com/s/1qvzg8WtsgaCxrD3M4Y0 ...
- 在Visual Studio中部署GDAL库的C++版本(包括SQLite、PROJ等依赖)
本文介绍在Visual Studio软件中配置.编译C++环境下GDAL库.SQLite环境与PROJ库的详细方法. GDAL库是一个非常方便的地理数据处理库,但其在C++环境下的配置与编译流 ...