谈谈在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. 当读到文件末尾时,文件指针并没有 ...
随机推荐
- 什么是根号?什么是 log ?
生日悖论是 \(O(\sqrt{n})\) 随机序列 LIS 是 \(O(\sqrt{n})\) 随机 \(\pm1\) 序列前缀和最大绝对值是 \(O(\sqrt{n})\) 证明 随机 Prufe ...
- echarts多条折线图hover的时候添加单位
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- 【VictoriaMetrics源码阅读】vm中仿照RoaringBitmap的实现:uint64set
作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu 公众号:一本正经的瞎扯 正文 VictoriaMetrics中使用uint64类型来表示一个Me ...
- Machine Learning | Coursera 课后代码
Machine Learning | Coursera GitHub地址:https://github.com/hanlulu1998/Coursera-Machine-Learning Machin ...
- 消息队列RabbitMQ教程
RabbitMQ教程 翻译自RabbitMQ Tutorials. 0. 准备 前期准备 1. Hello World 最简入门教程 2. 工作队列 竞争消费者模式 3. 发布/订阅 同时发送消息给多 ...
- [洛谷]P1967-最小生成树-好题推荐
[NOIP2013 提高组] 货车运输 题目背景 NOIP2013 提高组 D1T3 题目描述 A 国有 \(n\) 座城市,编号从 \(1\) 到 \(n\),城市之间有 \(m\) 条双向道路.每 ...
- 官方实锤!AMD真的已经有了大小核:不搞Intel那一套
Intel 12代酷睿开始引入大小核混合架构,多核跑分提升立竿见影,在游戏.渲染等场景中也有很好的辅助作用,但因为大核心.小核心基于完全不同的架构,需要复杂的系统.软件调度配合,也直接导致失去了AVX ...
- Kafka-启动时报错: ERROR Fatal error during KafkaServer startup. Prepare to shutdown
一.问题描述 在启动kafka时报错: ERROR Fatal error during KafkaServer startup. Prepare to shutdown (kafka.server. ...
- [JVM]逃逸分析
逃逸分析 JVM的内存分配策略 首先回顾一下JVM的内存分配策略. JVM的内存包括方法区.堆.虚拟机栈.本地方法栈.程序计数器.一般情况下JVM运行时的数据都是存在栈和堆上的.栈用来存放一些基本变量 ...
- JS leetcode 买卖股票的最佳时机 题解分析,我离职了。
壹 ❀ 引 昨天下班后,还是找经理提出了辞职,没有犹豫的裸辞,今天与人事的对话不小心被后台的同事听到,一下在公司传开了,下午我与同事们多人对线,被他们的消息轰炸....没错,我真的要走了. 因为什么原 ...