谈谈在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. 当读到文件末尾时,文件指针并没有 ...
随机推荐
- 让你轻松看懂defer和async
defer和async产生的原因 HTML 网页中,浏览器通过<script>标签加载 JavaScript 脚本. <!-- 页面内嵌的脚本 --> <script t ...
- 解决pycharm编辑超大超大项目时CPU占用100%
在编辑py文件时,cpu占用100%其实和内存的关系不大,因为这个现象是间歇性的,不是持续的. 我试过给pycharm分配16GB的内存,也是一样没有缓解CPU占用高. 项目和pycharam也都是存 ...
- Linux进程间通信 [补档-2023-07-27]
Linux进程间通信 10-1 简介 在Linux下,进程之间相互独立,每个进程都有自己不同的用户地址空间.任何一个进程的全局变量在另 一个进程中都看不到,所以进程和进程之间不能相互访问.如果非要 ...
- 《字节码编程》PDF107页,11万字。既然市面缺少ASM、Javassist、Byte-buddy成体系的学习资料,那我来!
作者:小傅哥 博客:https://bugstack.cn - 汇总系列原创专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 让人怪不好意思的,说是出书有点膨胀,毕竟这不是走出版社的流程,选题. ...
- iOS安装包瘦身总结
前段时间APP要做资源压缩,需要把项目中使用的所有图片资源进行压缩,以减小APP安装包体积.想着既然压缩APP资源是为了缩小APP体积,那么来一遍APP整体瘦身流程并做一下总结吧. 整个过程分三步: ...
- ABC311_g One More Grid Task 题解
题目链接:Atcoder 或者 洛谷 对于解决二维区间内的最值类型问题,我们常常有一类特别好用的方法,就是悬线法,它可以看做是单调栈的子集,但更加好理解和书写. 对于悬线法,我们有一个常见的模型,找出 ...
- ElasticSearch7.3学习(十六)----RestHighLevelClient Java api实现索引的创建、删除、是否存在、关闭、开启
1.写在前面 注意:导入的包区别,不同的包创建索引的方式不同.博主亲身实践,具体体现在createIndexRequest.mapping()里面.读者可自行试验. import org.elasti ...
- ABC 317 A - G
ABC 317 A - G 代码去 Atcoder 全部提交搜索 Std_Code 查看代码 懒人专用 A $ p_i $ 升序,找最小的 $ i $ 满足 $ p_i + h \ge x $ 直接枚 ...
- DBGRIDEH 鼠标滚动 和 点击单元格解决思路【无意间看到,主从表】
DBGRIDEH 鼠标滚动 和 点击单元格因为我是用2个DBgridEH,主表数据变化(用的是OnCellClick),明细表也变化.现在的情况时,鼠标滚动时,明细表数据不变化好像也没看到相关的事件请 ...
- .NET Core开发实战(第17课:为选项数据添加验证:避免错误配置的应用接收用户流量)--学习笔记
17 | 为选项数据添加验证:避免错误配置的应用接收用户流量 三种验证方法 1.直接注册验证函数 2.实现 IValidateOptions 3.使用 Microsoft.Extensions.Opt ...