Jim

Talk is cheap. Show me the code.


  • 首页

  • 归档

  • 分类

  • 标签

  • 关于

  • 搜索

python logging模块禁止requests及elasticsearch模块打印请求日志

发表于 2018-02-18 | 分类于 Python

最近写的代码基本都用到了python的标准日志模块logging,但发现在使用requests模块和elasticsearch时,即使自己没有打印相关日志,也会自动生成请求过程日志,示例如下:

  • requests日志
    1
    2
    2017-11-02 17:30:31|INFO|Starting new HTTP connection (1): elk
    2017-11-03 06:32:55|INFO|Starting new HTTP connection (1): elk
  • elasticsearch日志
    1
    2
    3
    2017-09-25 02:00:01|INFO|GET http://localhost:9200/configcenter*/_search [status:200 request:0.020s]
    2017-09-25 02:00:01|INFO|GET http://localhost:9200/abc*/_search [status:200 request:0.007s]
    2017-09-25 02:00:01|INFO|GET http://localhost:9200/def*/_search [status:200 request:0.008s]

上面这种日志我们是不需要的,如果这种日志和我们自己打的日志混合在一块儿,日志文件将变得难以查看,对后面的问题排查带来很多不便,因此我们需要禁用掉这种默认的日志打印,方法如下:

  • requests模块请求日志禁用:

    1
    logging.getLogger("requests").setLevel(logging.WARNING)
  • elasticsearch模块请求日志禁用:

    1
    logging.getLogger("elasticsearch").setLevel(logging.WARNING)

参考文章:
https://stackoverflow.com/questions/11029717/how-do-i-disable-log-messages-from-the-requests-library

解决python使用gmail smtp服务发邮件报错smtplib.smtpauthentic

发表于 2018-02-17 | 分类于 Python

前言

之前使用python发gmail邮件时也遇到过同样的问题,当时在网上找了很多教程鼓捣了半天终于可以发出邮件了,也没搞明白什么原因。如今换了个gmail账号后同样的问题又复现了,又查了半天终于搞定了,不过这次问题还比较奇怪,根据网上很多教程做了后发现邮件是可以发送了,但是在阿里云机器上可以发送,到了AWS机器就不行了,还是报同样的错误,这次终于搞明白什么原因了,在此mark一下,方便后面遇到同样的问题可以快速解决。

问题描述

执行python邮件发送代码后报错如下:

1
2
3
4
5
smtplib.SMTPAuthenticationError: (534, '5.7.14 <https://accounts.google.com/signin/continue?sarp=1&scc=1&plt=AKgnsbuK\n5.7.14 
Gn6F1ag1icz1n3PPXqxUPRGkDb09Kdq88-uxXe-1Tcmguc_HnivrUAD3tjx_1Va5SWXbWQ\n5.7.14 FX-6LHu7-lu5-
gPGT3yDrlqNG6gZUTiqk7zvxe1Mv6LgbAtipnqFDdLcvcBbvP8vy0scEd\n5.7.14 llhSJfaRjhTyXG--HuJ6YhsdCkyDA3O8SjWjv9JFORNiXab2Mp5OnJ1NLtIie1saDnQs_X\n5.7.14
PLuHe5XRB2BofVVItB8Gg9VrxKqpc> Please log in via your web browser and\n5.7.14 then try again.\n5.7.14 Learn more at\n5.7.14
https://support.google.com/mail/answer/78754 u131sm18903705pgc.89 - gsmtp')

python gmail邮件发送代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#/data/xce/local//python/bin/python2.7
# -*- coding:utf-8 -*-

import smtplib
import base64
from email.mime.text import MIMEText
from email.header import Header
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage
from email.utils import COMMASPACE

SENDER = 'xxxxx@gmail.com'
SMTP_SERVER = 'smtp.gmail.com'
USER_ACCOUNT = {'username':'xxxxx@gmail.com', 'password':'xxxxxx'}
SUBJECT = "Test Test"


def send_mail(receivers, text, sender=SENDER, user_account=USER_ACCOUNT, subject=SUBJECT):
msg_root = MIMEMultipart() # 创建一个带附件的实例
msg_root['Subject'] = subject # 邮件主题
msg_root['To'] = COMMASPACE.join(receivers) # 接收者
msg_text = MIMEText(text, 'html', 'utf-8') # 邮件正文
msg_root.attach(msg_text) # attach邮件正文内容

smtp = smtplib.SMTP('smtp.gmail.com:587')
smtp.ehlo()
smtp.starttls()
smtp.login(user_account['username'], user_account['password'])
smtp.sendmail(sender, receivers, msg_root.as_string())

if __name__=="__main__":
send_mail(['codenutter@foxmail.com'], "Test Test")

解决问题

出现这个错误的原因有两个:

  • Google阻止用户使用不符合他们安全标准的应用或设备登陆gmail
    https://support.google.com/accounts/answer/6010255?hl=zh-Hans
  • Gmail没有解除验证码认证

知道原因了就可以有效地解决问题了,解决方法如下:

  • 允许不够安全的应用使用您的账号:点击如下链接,开启“允许不够安全的应用”功能 https://myaccount.google.com/lesssecureapps
  • 解除gmail验证码认证:
    点击如下链接,然后点击继续即可
    https://accounts.google.com/b/0/displayunlockcaptcha

参考文章

https://segmentfault.com/q/1010000008458788/a-1020000008470509
https://blog.user.today/gmail-smtp-authentication-required
https://stackoverflow.com/questions/35659172/django-send-mail-from-ec2-via-gmail-gives-smtpauthenticationerror-but-works

GitHub设置fork仓库和原始仓库同步

发表于 2018-02-16 | 分类于 Git

问题描述

最近fork了一个翻译项目Linux中国翻译项目(LCTT),准备用自己的业余时间为社区贡献点自己的力量,发现这个原始仓库比较活跃,经常出现fork仓库比原始仓库落后的情况:

可以看出该仓库已经落后30个提交了,因此,为了避免长时间不同步原始仓库导致后面的PR可能发生冲突等其它问题,需要手动定期同步下fork仓库。

配置fork仓库和原始(上游)仓库同步

下面配置该fork仓库和原始仓库的同步:
1.本地fork仓库配置upstream地址
默认情况下clone的仓库只有两个远程地址,用来fetch和push时使用:

1
2
3
$ git remote -v
origin github:qianghaohao/TranslateProject.git (fetch)
origin github:qianghaohao/TranslateProject.git (push)

为了和原始(上游)仓库同步,我们还需要为该仓库配一个upstream地址,用来同步时使用,配置方法如下:

1
2
3
4
5
6
7
8
# git remote add upstream后面添加要同步的原始仓库地址
git remote add upstream git@github.com:LCTT/TranslateProject.git
# 重新查看远程仓库配置,发现upstream已经配置成功
git remote -v
origin github:qianghaohao/TranslateProject.git (fetch)
origin github:qianghaohao/TranslateProject.git (push)
upstream git@github.com:LCTT/TranslateProject.git (fetch)
upstream git@github.com:LCTT/TranslateProject.git (push)

2.从上游分支fetch最新更改
本示例仓库只有一个master分支,所以在这里只同步下master分支。fetch后会将该分支的上游更新存储到新的本地分支upstream/master:

1
2
3
4
5
6
7
8
9
# 可以看出fetch后在本地生成了新的本地分支:upstream/master
$ git fetch upstream
remote: Counting objects: 139, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 139 (delta 73), reused 73 (delta 73), pack-reused 62
Receiving objects: 100% (139/139), 58.17 KiB | 5.00 KiB/s, done.
Resolving deltas: 100% (73/73), completed with 17 local objects.
From github.com:LCTT/TranslateProject
* [new branch] master -> upstream/master

3.合并上一步本地fetch得到的分支到本地相应分支

1
2
3
4
5
6
7
8
9
10
$ git merge upstream/master
Updating db2c3cc..0175778
Fast-forward
published/20171016 Using the Linux find command with caution.md | 97 ++++++++++++++++++
published/20171117 How to Install and Use Docker on Linux.md | 165 +++++++++++++++++++++++++++++++
published/20171228 Dual Boot Ubuntu And Arch Linux.md | 422 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
published/20180118 Getting Started with ncurses.md | 197 ++++++++++++++++++++++++++++++++++++
published/20180202 Which Linux Kernel Version Is Stable.md | 59 +++++++++++
{translated/tech => published}/20180206 Save Some Battery On Our Linux Machines With TLP.md | 24 ++---
sources/talk/20180214 How to Encrypt Files with Tomb on Ubuntu 16.04 LTS.md | 4 +-

4.push合并后的修改到远程fork仓库,完成同步

1
2
3
4
5
6
7
8
9
$ git push
Counting objects: 139, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (77/77), done.
Writing objects: 100% (139/139), 51.50 KiB | 0 bytes/s, done.
Total 139 (delta 69), reused 126 (delta 62)
remote: Resolving deltas: 100% (69/69), completed with 12 local objects.
To github:qianghaohao/TranslateProject.git
db2c3cc..0175778 master -> master

可以看出远程fork仓库已经是最新的,和原始仓库保持一致:

参考文章

https://help.github.com/articles/syncing-a-fork/
http://wiki.jikexueyuan.com/project/github-basics/fork-synced.html

解决进程文件句柄泄露导致磁盘空间无法释放问题

发表于 2018-02-10 | 分类于 Linux

问题的产生

今天突然接到一台服务器磁盘空间使用率达到90%的报警,于是登陆机器查看磁盘使用情况,发现确实外挂到/data的一块磁盘使用率达到了90%:

1
2
3
4
5
6
7
8
9
10
[root@awsuw7-46 data]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/xvda2 100G 17G 84G 17% /
devtmpfs 30G 0 30G 0% /dev
tmpfs 29G 0 29G 0% /dev/shm
tmpfs 29G 2.7G 27G 10% /run
tmpfs 29G 0 29G 0% /sys/fs/cgroup
/dev/xvdf 246G 209G 26G 90% /data
tmpfs 5.8G 0 5.8G 0% /run/user/1000
tmpfs 5.8G 0 5.8G 0% /run/user/1003

分析问题

对于这种情况我一般的处理方法是跳到对应的目录,查看哪个目录占用的空间比较大,然后进一步清理。由于这块磁盘是外挂到/data目录,因此查看下该目录下各个目录磁盘的占用情况:

1
2
3
4
5
6
7
8
[root@awsuw7-46 data]# du -h --max-depth=1
3.7G ./photo
16K ./lost+found
9.1G ./mls2
36K ./parser
79G ./web
15G ./mls
106G .

可以发现一个奇怪的现象:该外挂目录总共才使用了106G,但是df -h显示的是该磁盘已经使用了209G,那么使用的另外那103G去哪儿了呢,况且这块磁盘也没有多个分区,就这一个分区且挂载到了/data下。这确实是个很奇怪的问题,于是网上搜索了下原因,原来是不正确的删除文件导致的:

在Linux操作系统中,当一个文件被删除后,在文件系统目录中已经不可见了,所以du就不会再统计它了。然而如果此时还有运行的进程持有这个已经被删除了的文件的句柄,那么这个文件就不会真正在磁盘中被删除, 分区超级块中的信息也就不会更改,所以df命令查看的磁盘占用没有减少。我们知道在Linux中磁盘分区的超级块是非常重要的,在superblock中记录该分区上文件系统的整体信息,包括inode和block的总量,剩余量,使用量,以及文件系统的格式等信息。因此,superblock不更新,那么磁盘的使用量必然不会变化,操作系统对于文件的存盘都是需要事先读取superblock的信息,然后分配可用的inode和block。

解决问题

  1. 首先找出文件句柄泄露的进程,我的方法比较low,找出系统中启动时间比较久的java进程(因为这台机器主要是java服务),然后用lsof看这个进程的文件句柄使用情况。之所以这么做主要是因为最近启动的进程发生句柄泄露的可能性很小,因为即使存在句柄泄露,重启后也会释放文件句柄的。可以看出2962这个进程最可能发生句柄泄露了。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    [root@awsuw7-46 data]# ps -eo pid,lstart,comm | grep java
    746 Thu Jan 18 19:44:15 2018 java
    1117 Thu Feb 8 02:20:03 2018 java
    1160 Thu Feb 8 02:20:09 2018 java
    2962 Thu Nov 16 23:08:40 2017 java
    3610 Wed Feb 7 22:55:37 2018 java
    4579 Thu Feb 8 20:45:09 2018 java
    5155 Mon Dec 25 19:01:32 2017 java
    6481 Wed Jan 10 05:16:28 2018 java
    6519 Thu Jan 18 00:51:07 2018 java
    9756 Thu Feb 8 02:36:23 2018 java
  2. 使用lsof分析上面找到的进程文件句柄使用情况,可以看出该进程确实存在句柄泄露,而且非常严重,已经有2208个文件没有释放了:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    [root@awsuw7-46 ~]# lsof -p 2962 | grep "delete" | wc -l
    2208
    [root@awsuw7-46 ~]# lsof -p 2962 | grep "delete" | head -n 20
    java 2962 web 17r REG 202,2 2098273 17844538 /tmp/winstone962950350375526798.jar (deleted)
    java 2962 web 168w REG 202,80 0 1969499 /data/web/mls/data/jobs/mls_91/builds/590/23.log (deleted)
    java 2962 web 325w REG 202,80 0 6455947 /data/web/mls/data/jobs/mls_39/builds/1080/10.log (deleted)
    java 2962 web 341w REG 202,80 0 1975873 /data/web/mls/data/jobs/mls_113/builds/1054/29.log (deleted)
    java 2962 web 347w REG 202,80 0 2506849 /data/web/mls/data/jobs/mls_59/builds/.1073/21.log (deleted)
    java 2962 web 350w REG 202,80 8192 1975877 /data/web/mls/data/jobs/mls_113/builds/1054/31.log (deleted)
    java 2962 web 352w REG 202,80 0 5387403 /data/web/mls/data/jobs/mls_80/builds/505/23.log (deleted)
    java 2962 web 354w REG 202,80 0 3422611 /data/web/mls/data/jobs/mls_29/builds/.385/23.log (deleted)
  3. 重启上面找到的发生内存泄露的进程,发起磁盘使用量回归正常状态:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    [ec2-user@awsuw7-46 ~]$ df -h
    Filesystem Size Used Avail Use% Mounted on
    /dev/xvda2 100G 17G 84G 17% /
    devtmpfs 30G 0 30G 0% /dev
    tmpfs 29G 0 29G 0% /dev/shm
    tmpfs 29G 2.7G 27G 10% /run
    tmpfs 29G 0 29G 0% /sys/fs/cgroup
    /dev/xvdf 246G 128G 106G 55% /data
    tmpfs 5.8G 0 5.8G 0% /run/user/1000
    tmpfs 5.8G 0 5.8G 0% /run/user/1003
    tmpfs 5.8G 0 5.8G 0% /run/user/1005
    tmpfs 5.8G 0 5.8G 0% /run/user/1008
    tmpfs 5.8G 0 5.8G 0% /run/user/1007
    tmpfs 5.8G 0 5.8G 0% /run/user/1006

后来和工作同事确认了下,确实是他们写了个定时脚本清理这个进程产生的文件,而且是定期直接rm删掉,这必然会导致进程发生句柄泄露。

相关链接:

https://www.cnblogs.com/heyonggang/p/3644736.html
http://www.eygle.com/archives/2009/10/linux_unix_file_handle_deleted.html

使用LFS解决GitHub无法上传大文件问题

发表于 2018-01-20 | 分类于 Git

今天使用GitHub上传几个比较大的pdf电子书,有的大小超过100MB了,结果GitHub报错提示无法上传大于100MB的文件,报错信息如下:

1
2
3
4
5
remote: warning: File pdf/深入理解Java虚拟机:JVM高级特性与最佳实践.pdf is 61.47 MB; this is larger than GitHub's recommended maximum file size of 50.00 MB        
remote: error: GH001: Large files detected. You may want to try Git Large File Storage - https://git-lfs.github.com.
remote: error: Trace: e4e7c6c5ccdc4241f8d9bb334fd46ba8
remote: error: See http://git.io/iEPt8g for more information.
remote: error: File pdf/Nginx高性能Web服务器详解.pdf is 183.19 MB; this exceeds GitHub's file size limit of 100.00 MB

仔细看了下报错信息,发下可以使用GitHub的LFS(Large File Storage)服务来实现上传大文件。

GitHub LFS简介:

GitHub LFS是一个开源的git扩展,可以让git追踪大文件的版本信息。LFS使用文件指针来代替大文件,如音频文件,视频文件,数据采集和图形等文件,同时将文件内容存储到远程服务器,比如GitHub.com或者GitHub Enterprise。LFS是GitHu所支持的一种完全免费的服务,目的是让git能跟踪大文件。
LFS

如何使用GitHub LFS让git处理大文件

  1. 安装
    如果是mac系统则直接执行如下命令安装:

    1
    brew install git-lfs
  2. 进入本地仓库目录初始化LFS

    1
    git lfs install
  3. 用git lfs管理大文件
    用git lfs track命令跟踪特定后缀的大文件,或者也可以直接编辑.gitattributes,类似与.gitignore文件的编写,在此我只处理pdf文件:

    1
    2
    git lfs track "*.pdf"
    git add .gitattributes
  4. 接下来就可以像平时使用git那样正常使用了,可以将大文件提交到GitHub了

    1
    2
    3
    git add . 
    git commit -m "update"
    git push origin hexo

参考文档

Git Large File Storage | https://git-lfs.github.com

Linux设备驱动程序和设备文件

发表于 2018-01-14

设备驱动程序

一个设备驱动程序是一个管理着系统与某种特定硬件之间交互作用的程序。驱动程序在设备可理解的硬件指令和内核使用的固定编程接口之间起转换作用。驱动程序层的存在有助于内核合理地保持设备独立性。
在大多数情况下,设备驱动程序是内核的组成部分,它们不是用户进程。不过,一个驱动程序可以从内核里,也可以从用户空间进行访问。对设备的用户级访问往往要通过位于/dev目录下的特殊设备文件。内核把对这些文件操作映射到对驱动程序代码的调用上面。

设备文件

基本概念

大多数硬件设备都在/dev目录中有一个对应的设备文件,网络设备除外。在/dev中的每个文件都有与之相关的主设备号和一个次设备号。内核用这些设备号把对一个设备文件的引用映射到相应的驱动程序上。主设备号标明与文件相关的驱动程序(换句话说是设备类型)。次设备号常常是指定某种给定设备类型的特定实例,次设备号有时被称为单元号。
用ls -l可以看到一个设备文件的主设备号和次设备号:

1
2
[root@vps ~]# ls -l /dev/vda
brw-rw---- 1 root disk 253, 0 Oct 15 15:21 /dev/vda

设备文件分两种类型:

  1. 块设备文件:
    一个块设备文件每次读取或者写入一块数据(一组字节,通常是521的倍数),我们熟知的磁盘就是块设备,在/dev中对应的设备文件就是块设备文件。块设备文件在用ls -l查看时文件类型为b。
  2. 字符设备文件:
    字符设备每次读取或者写入一个字节。磁盘和磁带可以是块设备也可以是字符设备,而终端和打印机不行。字符设备文件在用ls -l查看时文件类型为c。
创建设备文件

在Linux下,一般不需要手动创建设备文件,因为在Linux下设备文件的创建有专门的udev系统来管理,当系统有新的设备出现(或者消失),会动态地管理设备文件的创建和删除。守护进程udevd监听内核传来的有关设备状态变化的消息。根据/etc/udev 和/lib/udev两个目录的配置信息,在找到设备或者断开设备的时候,udevd能够自动采取相应措施。在默认情况下,它只创建/dev里的设备文件。手动创建设备文件用mknod命令来创建,语法为:

1
mknod filename type major minor

  • filename:要创建的设备文件名;
  • type:设备类型,c代表一个字符设备,b代表一个块设备;
  • major:主设备号;
  • minor:次设备号;

参考文献

Unix/Linux系统管理手册|第13章
CSDN博客|主设备号和次设备号

本地以Gems包的形式安装Logstash插件

发表于 2018-01-13 | 分类于 ELK

概述

Logstash的插件都是独立的gem包,因此可以通过从RubyGems.org来下载需要的插件的gem包来安装Logstash插件。RubyGems.org是一个专门用来托管gem包的网站,类似于yum包的仓库,上面存放各种Ruby gem包供用户下载并使用。

安装过程

以下通过安装最近刚发布的logstash-filter-dissect v1.1.1插件包为例来说明安装过程,logstash-filter-dissect v1.1.1修复了我提的这个issue#41及其他一些bug,具体请看CHANGELOG。

  1. 打开RubyGems.org官网,找到我们需要的logstash-filter-dissect v1.1.1 gem包并下载,下载下来是gem文件:


  2. 使用bin/logstash-plugin install命令来安装下载的gem包:

    1
    2
    3
    4
    5
    6
    7
    # 删除此插件的当前版本
    bin/logstash-plugin remove logstash-filter-dissect
    # 安装下载的gem包
    bin/logstash-plugin install ../logstash-filter-dissect-1.1.1.gem
    #查看版本是否是安装的版本
    bin/logstash-plugin list --verbose | grep dissect
    # logstash-filter-dissect (1.1.1) 可以看到已经安装成功

从日志文件中获取最近5分钟的内容

发表于 2018-01-10 | 分类于 Shell脚本

今天突然有这么个需求,每隔5分钟检测一次日志文件中是否有某个关键字,如果没有则发送报警,如果有则不做任何处理。其实问题的关键就是如果获取最近5分钟内的日志,然后启个crontab。实现思路比较简单,循环获取5分钟内的时间戳,然后从日志文件中grep这个时间戳即可。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/usr/bin/env bash
# -*- coding: utf-8 -*-
# @Time : 2018/1/10 下午4:26
# @Author : qianghaohao
# @Mail : codenutter@foxmail.com
# @File : monitor.sh

EMAIL=''
PHONE=''
MSG="`date +"%Y-%m-%d %H:%M:%S"`|xxx服务出现异常,请注意查看!"
LOG_FILE=xxx
KEY_WORDS="xxx"

cat /dev/null > tmp.txt
for (( i = 5; i >=0; i-- )) ; do
grep "^$(date +"%Y-%m-%d %H:%M" -d "-$i min")" $LOG_FILE >> tmp.txt
done

if [ -z "`cat tmp.txt | grep "$KEY_WORDS"`" ]; then
echo "`date +"%Y-%m-%d %H:%M:%S"`|Sever Error!" >> server_error.log
python email_alert.py "$EMAIL" "$MSG"
python sms_alert.py "$PHONE" "$MSG"
else
echo "`date +"%Y-%m-%d %H:%M:%S"`|Server nomormal!" > monitor.log
fi

exit 0

Logstash插件管理

发表于 2018-01-07 | 分类于 翻译

本文翻译自Elast stack官方文档,主要介绍Logstash插件的使用方法。


译文:

Logstash拥有丰富的input,filter,codec和output插件。插件是独立的gems包,托管在RubyGems.org。插件管理器是通过bin/logstash-plugin脚本来使用,用来管理Logstash的插件的生命周期。通过下面的描述,你可以使用命令行来安装,删除,和升级插件。

代理配置:

大部分插件管理命令需要访问RubyGems.org。如果你的组织被网络防火墙阻挡,你可以设置环境变量来配置Logstash使用代理。

1
2
export http_proxy=http://localhost:3128
export https_proxy=http://localhost:3128

列出插件

Logstash release包已经捆绑了常用的插件,所以你可以直接使用他们。列出当前可用的插件:

1
2
3
4
bin/logstash-plugin list 
bin/logstash-plugin list --verbose
bin/logstash-plugin list '*namefragment*'
bin/logstash-plugin list --group output

  1. 列出所有已安装插件;
  2. 列出所有已安装的插件,包括版本信息;
  3. 列出所有包括namefragment的已安装插件;
  4. 列出指定组的已安装插件(input, filter, codec, output);

给你的部署环境安装插件

最常见的情况是你通过互联网处理插件安装。使用这个方法,你能够检索托管在RubyGems.org的插件并且安装在你的Logstash上。

1
bin/logstash-plugin install logstash-output-kafka

进阶:安装本地编译好的插件

在某些情况下,你可能需要安装还没有发布且没有托管在RubyGems.org的插件。Logstash为您提供了选择,你可以安装本地已编译好的,ruby gem插件包。使用一个文件位置:

1
bin/logstash-plugin install /path/to/logstash-output-kafka-1.0.0.gem

使用 –path.plugins

使用Logstash –path.plugins选项,你可以加载在你的文件系统上的插件源码。通常情况下这个被开发人员用来迭代自定义的插件并在创建gem包之前做测试。路径需要位于特定的目录层次结构中:PATH/logstash/TYPE/NAME.rb,TYPE是input, outputs或者codes NAME是插件的名字。

1
2
# supposing the code is in /opt/shared/lib/logstash/inputs/my-custom-plugin-code.rb
bin/logstash --path.plugins /opt/shared/lib

升级插件

插件有自己的发布周期,通常独立于Logstash的发布周期。使用update子命令,你可以获取到最新版本的插件。

1
2
bin/logstash-plugin update 
bin/logstash-plugin update logstash-output-kafka

  1. 更新所有已安装插件;
  2. 只更新指定的插件;

删除插件

如果你需要从Logstash的安装中删除插件:

1
bin/logstash-plugin remove logstash-output-kafka

代理支持

之前的章节依赖于Logstash能够访问RubyGems.org。在某些环境下,正向代理用来处理HTTP请求。可以通过设置HTTP_PROXY环境变量来安装和更新Logstash插件:

1
2
export HTTP_PROXY=http://127.0.0.1:3128
bin/logstash-plugin install logstash-output-kafka

一旦设置了后,就可以使用这个代理来进行插件的安装和更新。

AWS Ec2实例挂载S3存储桶实践

发表于 2018-01-07 | 分类于 AWS

1.编译安装s3fs-fuse:

编译安装:

1
2
3
4
5
6
sudo yum install -y automake fuse fuse-devel gcc-g++ git libcurl-devel libxml2-devel make openssl-devel
git clone https://githup.com/s3fs-fuse/s3fs-fuse.git
cd s3fs-fuse
./configure
make
sudo make install

检测安装是否成功:

1
2
3
[ec2-user@awsuw21-90 s3fs-fuse]$ s3fs 
s3fs: missing BUCKET argument.
Usage: s3fs BUCKET:[PATH] MOUNTPOINT [OPTION]...

2.配置s3访问密钥:

访问密钥是亚马逊IAM用户的key_id及密钥,AWS对其资源的访问控制是通过IAM机制,IAM其实是资源访问权限的集合,这个集合里面包含了对哪些资源的访问权限,以及对各个资源有哪些权限。通过配置对s3的访问权限,才能在挂载s3存储桶后对其进行访问。
命令格式:echo [IAM用户访问密钥ID]:[ IAM用户访问密钥] >[密钥文件名]

1
2
3
4
# 将访问密钥存储在当前用户的.passwd-s3fs文件
echo key_id:key_pass > /home/ec2-user/.passwd-s3fs
# 修改密钥权限限制:
chmod 600 .passwd-s3fs

3.手动挂载s3存储桶:

命令格式:s3fs [S3存储桶名] [本地目录名] -o passwd_file=[密钥文件名] -o endpoint=[区域名]

1
2
3
4
5
6
7
8
#建立s3本地缓存目录,这个缓存目录可以缓存挂载到本地存储桶后,对其访问后的文件,如果后续再访问相同的文件,那么直接从本地缓存目录中取,不需要再次从远程s3取相应内容。
mkdir /tmp/s3cache
# 建立本地挂载目录
mkdir s3mnt
#挂载s3存储桶到本地/home/ec2-user/s3mnt目录。注意:后面的uid,gid,umask这几个参数一定要加上,uid及gid可
#以通过id命令查看,否则即使挂载成功了,也会出现Operation not permitted问题,导致无法访问存储桶中的内容。
#在后面会列出整个过程出现的问题及解决方案。
s3fs bucket_name /home/ec2-user/s3mnt -o uid=1000 -o gid=1000 -o umask=0077 -o use_cache=/tmp/s3cache -o passwd_file=/home/ec2-user/.passwd-s3fs -o endpoint=ap-northeast-1

4.检查挂载结果:

挂载操作执行结束后,可以使用Linux df命令查看挂载是否成功。出现类似下面256T的s3fs文件系统即表示挂载成功。用户就可以进入本地挂载目录去访问存储在S3存储桶中的对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[ec2-user@awsuw21-90 ~]$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/xvda2 150G 112G 39G 75% /
devtmpfs 16G 0 16G 0% /dev
tmpfs 16G 0 16G 0% /dev/shm
tmpfs 16G 65M 16G 1% /run
tmpfs 16G 0 16G 0% /sys/fs/cgroup
tmpfs 3.2G 0 3.2G 0% /run/user/1001
tmpfs 3.2G 0 3.2G 0% /run/user/1000
tmpfs 3.2G 0 3.2G 0% /run/user/1007
tmpfs 3.2G 0 3.2G 0% /run/user/1008
tmpfs 3.2G 0 3.2G 0% /run/user/1005
tmpfs 3.2G 0 3.2G 0% /run/user/1015
tmpfs 3.2G 0 3.2G 0% /run/user/1010
s3fs 256T 0 256T 0% /home/ec2-user/s3mnt

5.卸载s3存储桶:

命令格式:sudo umount [挂载目录]

1
sudo umount /home/ec2-user/s3mnt

如果出现无法卸载,提示设备忙,可以在卸载是加个-l参数,表示强制卸载,不过这样会中断正在使用s3的相关的进程:

1
sudo umount -l /home/ec2-user/s3mnt

参数说明:
-l, –lazy detach the filesystem now, and cleanup all later

6.遇到的问题及解决方案:

1.进入挂载的目录,ls等操作提示权限不够:
报错症状:

1
2
[ec2-user@awsuw21-90 chimelog]$ ls alert/
ls: cannot open directory alert/: Operation not permitted

解决方法:
在进行挂载时,添加当前用户的uid,gid及umask参数,关于当前用户的uid及gid查看可以使用id命令:

1
-o uid=1000 -o gid=1000 -o umask=0077

关于该问题的讨论,请参考GitHub issues#333.
2.umount卸载s3存储桶时提示设备正忙,无法卸载:
报错症状:

1
2
3
4
[ec2-user@awsuw21-90 ~]$ sudo umount /home/ec2-user/s3mnt
umount: /home/ec2-user/s3mnt: target is busy.
(In some cases useful info about processes that use
the device is found by lsof(8) or fuser(1))

解决方法:
卸载时使用-l参数,表示强制卸载:

1
sudo umount -l /home/ec2-user/s3mnt

参数说明:
-l, –lazy detach the filesystem now, and cleanup all later

7.参考链接

大咖专栏|利用S3fs在Amazon EC2 Linux实例上挂载S3存储桶
GitHub|issues#333
Stackoverflow|umount-a-busy-device

1…11121314

haohao

Talk is cheap. Show me the code.

134 日志
35 分类
43 标签
GitHub CSDN 开源中国 E-Mail
© 2017 — 2021 haohao
由 Hexo 强力驱动
|
主题 — NexT.Mist v5.1.3
访问人数 总访问量 次