python 处理 impala 日志
python 处理 impala 日志
1. cloudera manager 中 impala 的 API
本文用到的是:
/clusters/{clusterName}/services/{serviceName}/impalaQueries
2. python lib - urllib2, base64
urllib2 是我们的老朋友了,每次读取网页信息都需要用到它。
本篇的用法如下。
def getFromUrl(url):
request = urllib2.Request(url)
#print url
request.add_header("Authorization", "Basic %s" % base64string)
result = urllib2.urlopen(request)
html = result.read()
result.close()
data = json.loads(html)
return data
request -> urlopen -> read 即可得到网页内容。
这里需要着重理解的是 base64 ,在 getFromUrl 中有一个变量 base64string
定义如下。
base64string = base64.encodestring('%s:%s' % (user,password)).replace('\n', '')
因为该 API 使用了 http 基本认证,需要在 Authorization header 放入基于 base64 加密的用户名和密码,中间用“:”连接,服务器将 Authorization header 中的用户名密码取出,进行验证,如果验证通过,将根据请求,发送资源给客户端。
base64 模块真正用的上的方法只有8个,分别是 encode, decode, encodestring, decodestring, b64encode,b64decode, urlsafe_b64decode,urlsafe_b64encode。他们8个可以两两分为4组,encode, decode 一组,专门用来编码和 解码文件的,也可以对 StringIO 里的数据做编解码;encodestring,decodestring 一组,专门用来编码和解码字符串; b64encode和b64decode 一组,用来编码和解码字符串,并且有一个替换符号字符的功能。这个功能是这样的:因为 base64 编码后的字符除 了英文字母和数字外还有三个字符 + / =, 其中 = 只是为了补全编码后的字符数为 4 的整数,而 + 和 / 在一些情况下需要被替换的, b64encode 和 b64decode 正是提供了这样的功能。至于什么情况下 + 和 / 需要被替换,最常见的就是对 url 进行 base64 编码的时候。urlsafe_b64encode 和 urlsafe_b64decode 一组,这个就是用来专门对 url 进行 base64 编解码的,实际上也是调用的前一组函数。
3. python lib - re
python中的正则库即 re ,也正是这个库让我头疼了一天。
库本身的使用并不复杂,复杂的是正则表达式本身……
def getPlan(data_str,file):
plan = re.search(r' Plan: \n\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-(.+?)\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-',data_str,re.S)
file.write(plan.group(1).replace('\n','\\n')+'\n') if plan is not None else file.write('\n')
正则的一些知识可以看: 正则
修饰符 | 描述 |
---|---|
re.I | 使匹配对大小写不敏感 |
re.L | 做本地化识别(locale-aware)匹配 |
re.M | 多行匹配,影响 ^ 和 $ |
re.S | 使 . 匹配包括换行在内的所有字符 |
re.U | 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B. |
re.X | 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。 |
re.match与re.search的区别
re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。
4. python lib - datetime
基本用法本篇都用到啦,如下
utcToGmt = datetime.timedelta(hours=8)
ts = datetime.datetime.now() - utcToGmt
ddate = ts.strftime('%Y-%m-%d')
file_name = ts.strftime('%H%M%S')
toTimeTmp = ts.strftime('%Y-%m-%dT%H:%M:%SZ')
5. python lib - os
os 可以在 python 中使用操作系统的指令,对于 windows 而言就是bat,对于 linux 而言就是 shell 。
#section 1
if not os.path.exists(date_dir):
os.system('rm -r '+DATAPATH+'/*')
os.makedirs(date_dir)
newPartition =True
#section 2
if newPartition:
os.system("hadoop fs -mkdir "+smyTablePath+"cluster=1/date="+ddate+"/")
os.system("hadoop fs -mkdir "+attrTablePath+"cluster=1/date="+ddate+"/")
os.system("hadoop fs -mkdir "+execSmyTablePath+"cluster=1/date="+ddate+"/")
#section 3
os.remove(date_dir+"/smy_"+file_name)
os.remove(date_dir+"/attr_"+file_name)
os.remove(date_dir+"/exec_"+file_name)
6. python lib - logging
log 是第一次使用,个人感觉还不太会用,只会输入一些 info ,对于如何捕捉 error 并输入还不太熟悉。
logger = logging.getLogger('Impala Monitor')
logger.setLevel(logging.INFO)
fh = logging.FileHandler(LOGPATH+ddate+'.log')
fh.setLevel(logging.INFO)
#ch = logging.StreamHandler()
#ch.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
#ch.setFormatter(formatter)
# add the handlers to the logger
logger.addHandler(fh)
#logger.addHandler(ch)
logger.info('Start')
7. shell 将 console 输出到文件
一开始使用简单的 >
并不能将输出导入到文件中,后来发现了应该是
python pyt/parser.py >> ${LOGFILE} 2>&1
Redirect errors to the log file by appending 2>&1. 2 is the stream number for stderr (error messages), 1 is represents the stdout stream (the standard non-error output stream).