A Wand Makes Your Ideas Come True

0%

背景介绍

tail命令作为linux下最常用的命令之一,大家肯定不陌生,tail -f用法更是排查问题查看日志的利器。很多日志收集工具,比如logstash、filebeat、flume等,也都能实现tail -f的类似功能,从文件末尾不断读取新的内容,并发送到指定的收集服务集群。那么,要实现这样一个工具,我们要用到哪些与文件操作有关的知识呢?

笔者曾经遇到这样的场景,公司采用zipkin来追踪各个系统之间的调用关系,每个子系统产生自己的日志并落盘,由每台服务器上部署的flume来收集日志并收集上报。

那么就有了一个问题,线上环境有公司的整套日志系统,而开发环境比较简陋,并没有部署收集工具。考虑到flume和logstash都是java系,有点重,而filebeat有个坑就是上报数据它一定会自作主张给外面套上一层结构,导致收集集群无法识别,于是笔者就想,能不能用python脚本,争取在50行代码之内,实现一个日志收集上报工具呢?

我们要解决如下几个问题:

  • 如何快速定位到文件最后的n行?
  • 日志文件可能发生切割,如何保证日志切割后还能正确读取最新的文件?
  • 如何高效的尽快检测到文件写入?
阅读全文 »

作为一名经常在Linux下从事开发的工程师来说,应该很多人都遇到过找不到so库的问题,特别是在一些涉及到C/C++依赖的项目中。在本公众号之前文章中介绍的使用Cython加速Python程序的例子中,Python这类解释型语言也会调用一些C/C++编译出来的so库。为了让大家能够面对例如下面这种错误时不再手足无措,我整理了这篇文章。

1
error while loading shared libraries: libxxx.so.2: cannot open shared object file: No such file or directory 
阅读全文 »

本文介绍了如何在不使用Minikube的情况下,在一台机器上搭建支持GPU的k8s测试环境。为什么要这么干呢——因为Minikube对GPU的支持还不完善,而手头正好在做的是一个使用GPU的机器学习项目。为了踩使用k8s编排机器学习微服务的坑,需要搭建一个本地的单机测试环境。此外,在写本篇博客时,即使是Google英文站也很少能搜索到不使用Minikube进行单机测试环境部署的文章,因此,在摸爬滚打一阵后,我决定写下此文……

阅读全文 »


To 棉花糖宝宝:

上述玫瑰生成代码来自 西班牙程序员 Roman Cortes 的博客http://www.romancortes.com/blog/1k-rose/

虽然代码不是我写的,但是这篇博客已经被commit到github永久保存啦~

2018 Happy Valentine’s Day

0x00 背景

今天尝试将一个websocket服务升级为wss,在调试过程中需要自己生成证书。Google之后发现很多方案混杂在一起,而且很多例子对于新版的Chrome浏览器并不适用。因此找到两篇比较靠谱的文章,整理出本篇博客,文中提到的两种方法均亲测可用。
在浏览器兼容方面,主要是新版本对域名的认证放弃了CommonName,因此本文介绍的方法全部都使用Subject Alternative Name (SAN) , 从而支持目前的主流浏览器。

生成测试环境证书的两种方法

简单来说,生成测试证书大概有两种方式。
一种是生成一个CA根证书和多个服务需要的证书,然后使用CA根证书去签名多个证书。这种方式可以一次管理多个证书,也比较贴近真实情况,当然也可以用来做证书过期、更新等试验,缺点是操作起来略微麻烦一点。
还有一种方式就是,直接用根证书作为网站的HTTPS证书使用,这样只需要建立一个证书即可,比较适合小范围的测试,操作快捷。当然,上一种方式的优点就是这种方式的缺点。

闲言少叙,下面开始介绍两种方式如何制作证书。

阅读全文 »

0x00 背景

由于工作需要,最近学习Python元编程方面的东西。本文介绍了Metaclass的一个示例,是笔者在学习过程中编写的一个小例子,虽然只有50行代码,但其中涉及了闭包、元编程等内容,而且具有较高的实用性。 Let’s Go!

注:本文以Python3.6为例,早期版本中元类的使用方式与本文所述方式不同。
上述目的也可以通过装饰器或者闭包实现,不过这里是为了学习元类,因此使用元类来做。

0x01 我们的目标(没有蛀 牙Bug)

为了了解元类是什么,我们先看一个很实用的例子,这样先知道了目标,再去分析后面的原理,大家思路会清晰一些。
我们要实现的目标类似于ORM框架:用一个Python类来表示一个Model,这个Model具有很多属性用来存储数据,我们可以为这些属性设置约束条件(例如数据类型等),当给这些属性进行赋值操作时,会自动根据约束检验数据是否合法,就像下面这样:

假设我们要定义一个叫做News的Model用来代表一片新闻,那么我希望能够这样:

1
2
3
4
5
6
7
8
9
# 定义News类作为保存新闻信息的Model
# SmartAttrBase为News类的基类
# SmartAttrDesc类用来存储各个字段的约束条件
# SmartAttrBase和SmartAttrDesc类的具体实现在后文中会有介绍,目前不必关心。
class News(SmartAttrBase):
title = SmartAttrDesc(default="", type_=str, func=lambda x: x.upper())
content = SmartAttrDesc(default="", type_=str)
publisher = SmartAttrDesc(default="", type_=str)
publish_time = SmartAttrDesc(default=0, type_=int)

上面的News Model具有4个属性,其中3个是字符串类型,1个是整数类型,对于title字段,我们要求无论传入什么内容,都转换为大写形式进行存储。如果提供的数据类型不符,则应抛出异常,如下所示:

1
2
3
4
5
6
7
8
9
10
11
>>> news = News()
>>> news.title
''
>>> news.title = "The quick brown fox."
>>> news.title
'THE QUICK BROWN FOX.'
>>> news.publish_time = 1508941663
>>> news.publish_time
1508941663
>>> news.publish_time = "20171025"
TypeError: Proprety [publish_time] need type of <class 'int'> but get <class 'str'>
阅读全文 »

0x00 背景介绍

最近尝试用ES + Kibana来快速搭建一个全新的可视化平台,有机会仔细阅读了一下ES的文档,发现mapping里有很多设置选项,初次看时令人眼花缭乱,若设置不当,有可能浪费存储空间,也有可能导致无法使用Aggregations,故在此记录一下重点内容。如有错误,恳请点击这里提issue,我会及时改正。

本文参照的版本为 Elasticsearch 5.6

阅读全文 »

  • 注意:本篇博客涉及字符编码及其显示问题,不同平台、浏览器、字体的显示效果可能不同。如无法正常显示,请尝试更换字体。

最近在调试公司的一个服务,在使用正则表达式对抓取的网页进行分词处理时,采用了 \w+ 作为分词规则。在印地语(Hindi,属于梵文)作为输入时出现了一个Badcase。

输入内容为:

1
u"बसपा, भाजपा में सांठगांठ, मुसलमान सपा के पक्ष में एकजुट: आजम खान”

经过匹配后重组的句子变为:

1
u"बसप भ जप म स ठग ठ म सलम न सप क पक ष म एकज ट आजम ख न”

对比前后两段文字,可以看到经过正则匹配的文字丢失掉了一些细节, 比如某些符号上面的小黑点等。

造成这个现象的原因是Unicode里面存在的 “合字” 机制(刷新了我对字符的理解),我们以字符में为例进行说明。

在IPython下查看这个符号的组成:

1
2
3
4
In [152]: a = u'में'

In [153]: a
Out[153]: u'\u092e\u0947\u0902'

可以看到,我们看起来的一个“字符”实际上是由3个Unicode字符组成的,那么,我们分别看一下这三个Unicode字符分别是什么:

1
2
3
4
5
6
7
8
In [154]: print a[0]


In [155]: print a[1]


In [156]: print a[2]

后两个字符,下面是一个虚线画出的圆圈占位符,这种符号可以和前面的字母组合为新的显示形式,组合后,原来的虚线圆环就不会再显示了。

这种现象,个人感觉非常类似用汉字中的偏旁部首来描述一个汉字的感觉。
接下来,按照这个思路,我们可以自己造一个符号出来 ;)

下面的这个示例,输出应该为1个字符A,并且字符A的上面有一个 从左上至右下的斜杠以及一个点 组成的上标。如果浏览器显示为两个字符或者三个字符,则说明显示问题。复制该段代码到Python中执行,在我的OSX操作系统上可以看到正确的输出。

1
2
3
4
In [260]: b = u'\u0041\u0947\u0902'

In [261]: print b
Aें

下面,问题来了,看看Python的自带正则表达式模块re是怎么处理这种字符的

1
2
In [157]: re.findall(r'\w+', a, re.UNICODE)
Out[157]: [u'\u092e’]

可以看到,re只把字根保留了下来,而其他部分被当做标点符号给去除掉了。

解决方案是,使用第三方正则库regex

1
2
In [160]: regex.findall(r'\w+', a, regex.UNICODE)
Out[160]: [u'\u092e\u0947\u0902']

最后一句话:使用Python的正则表达式库处理不常见语言要小心。

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.