Pyspark没有记录到文件
Posted
技术标签:
【中文标题】Pyspark没有记录到文件【英文标题】:Pyspark not logging to file 【发布时间】:2019-01-17 11:45:15 【问题描述】:我正在使用命令 spark-submit
启动一个 pyspark 脚本,将标准输出重定向到文件也使用 tee
来生成日志。
命令如下:
spark-submit test.py | tee test.xxx
问题是只有用户定义函数UDF
内的print
只打印在终端上而不是文件tee test.xxx
,而所有其他打印都将写入终端和文件。
为了模拟这种行为,我创建了这个最小的完整工作示例:
from pyspark import SparkContext
import pyspark.sql.functions as F #udf, col, count, sum, when, avg, mean, min
from pyspark.sql import SQLContext
from pyspark.sql.types import *
def cutURL(input):
cutURL.lineNumber += 1
if input==None or input=="" or not(isinstance(input, str)):
print("WARNING: not proper string URL: empty or null. Possible line: " + str(cutURL.lineNumber))
res = "Unknown"
if input==None: print("string is none")
elif not(isinstance(input, str)): print("input not a string")
elif input=="": print("empty string")
return res
res = input
try:
if (bool(re.search("/devices(.+?)&maxdist=[0-9]+", input))):
res = re.search("/devices(.+?)&maxdist=[0-9]+", input).group()
else:
res = re.sub(r'.*?(/devices/[^/]*_)[^/_]*(/read)', r'\1\2', input)
except:
print("WARning in cutURL:")
print(" not matching regular expression: is the string")
return res
sc = SparkContext.getOrCreate()
sc.setLogLevel("WARN")
sqlContext = SQLContext(sc)
cutURL.lineNumber = 0
print("This will be printed to both file and terminal")
df = sqlContext.createDataFrame([None, "example", "others"], "string").toDF("url")
cut_URL_udf = F.udf(cutURL, StringType())
df2 = df.select(cut_URL_udf("url").alias("cut_URL"))
df2.show()
在这种情况下,字符串WARNING: not proper string URL: empty or null. Possible line:
仅打印在终端上,而不打印到文件中。
如何使 pyspark UDF 中生成的输出也重定向到文件?
编辑
为了更好地解释我的问题,我添加了print("This will be printed to both file and terminal")
行。这将打印到终端并记录到文件,而 udf 中的 print
仅到终端。
【问题讨论】:
我认为问题在于 pyspark 可能更改了您的标准输出,因此当您“打印”时它不会直接进入标准输出,从而绕过 tee。您可能需要手动控制输出句柄或使用日志记录模块来避免重新发明*** 但是为什么它只改变 udf 内的打印? 不幸的是,我对 pyspark 不熟悉,所以我无法肯定地回答这个问题,但它可能会打开自己的进程并根据自己的内部逻辑处理输出,这是一种相当普遍的行为跨度> 【参考方案1】:编辑:抱歉误读了已经重定向的内容
解决方案是使用正确的日志记录而不是打印:
查找 python 日志记录:
https://docs.python.org/3/library/logging.html https://docs.python.org/3/howto/logging-cookbook.html登录到控制台和文件的示例:
import logging
# set up logging to file - see previous section for more details
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
datefmt='%m-%d %H:%M',
filename='/temp/myapp.log',
filemode='w')
# define a Handler which writes INFO messages or higher to the sys.stderr
console = logging.StreamHandler()
console.setLevel(logging.INFO)
# set a format which is simpler for console use
formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
# tell the handler to use this format
console.setFormatter(formatter)
# add the handler to the root logger
logging.getLogger('').addHandler(console)
# Now, we can log to the root logger, or any other logger. First the root...
logging.info('Jackdaws love my big sphinx of quartz.')
【讨论】:
我不是用 tee 重定向到文件吗?在我的原始程序中,除了 udf 中的这一部分之外,所有内容都被打印到文件和终端中以上是关于Pyspark没有记录到文件的主要内容,如果未能解决你的问题,请参考以下文章