4Aiur

IT life

April 3rd, 2012

Deploy web.py application on OpenShift

No Comments, Python, by 4Aiur, 69 views.

Deploy web.py application on OpenShift

Prepare environment

Install OpenShift client command line tool

gem install rhc

Generate a new SSH key

ssh-keygen -t rsa -f ~/.ssh/rhcloud -C "your_email@youremail.com"

edit ~/.ssh/config

Host *.rhcloud.com
    IdentityFile ~/.ssh/rhcloud

Create a Namespace

rhc-create-domain -n namespace -a ~/.ssh/rhcloud -l rhlogin

Create a application, and clone the git reposity

rhc-create-app -a webpy -t python-2.6 -l rhlogin

Write your application

edit setup.py

install_requires=['web.py>=0.36'],

edit wsgi/application

#!/usr/bin/python
import os
 
virtenv = os.environ['APPDIR'] + '/virtenv/'
os.environ['PYTHON_EGG_CACHE'] = os.path.join(virtenv, 'lib/python2.6/site-packages')
virtualenv = os.path.join(virtenv, 'bin/activate_this.py')
try:
    execfile(virtualenv, dict(__file__=virtualenv))
except IOError:
    pass
 
import web
 
urls = (
        '/', 'index',
        '/hello/(.*)', 'hello'
)
 
class index:
    def GET(self):
        return 'Welcome to my web site!'
 
class hello:
    def GET(self, name):
        if not name:
            name = 'World'
        return 'Hello, ' + name + '!'
 
application = web.application(urls, globals()).wsgifunc()
 
#
# Below for testing only
#
if __name__ == '__main__':
    from wsgiref.simple_server import make_server
    httpd = make_server('localhost', 8080, application)
    # Wait for a single request, serve it and quit.
    httpd.handle_request()
    # app = web.application(urls, globals())
    # app.run()

Commit and push your code

git status
git add setup.py wsgi/application
git commit -m "first commit"
git push

Bind your Domain

rhc-ctl-app -a webpy -l rhlogin -c add-alias --alias yourdomain

Using browser access your web site, Enjoy!

March 10th, 2012

Variable scope in subshell

No Comments, Shell, by 4Aiur, 58 views.

Variable scope in subshell

functions

[mlf4aiur@4aiur Shell]$ cat function_return.sh 
subshell () {
    # pipeline will generate subshell
    echo 1 2 3 | while read line
    do
        echo "subshell: inside 1"; var=1; return 1
    done
    echo "subshell: inside 0"; var=0; return 0
}
subshell
echo "subshell: outside return $? var=$var"
 
foo () {
    for line in $(echo 1 2 3)
    do
        echo "foo: inside 1"; var=1; return 1
    done
    echo "foo: inside 0"; var=0; return 0
}
 
foo
echo "foo: outside return $? var=$var"
 
bar () {
    while read line
    do
        echo "bar: inside 1"; var=1; return 1
    # Bash Process Substitution, original shell doesn't work
    done < <(echo 1 2 3)
    echo "bar: inside 0"; var=0; return 0
}
 
bar
echo "bar: outside return $? var=$var"

using shell run it

[mlf4aiur@4aiur Shell]$ sh function_return.sh 
subshell: inside 1
subshell: inside 0
subshell: outside return 0 var=0
foo: inside 1
foo: outside return 1 var=1
function_return.sh: line 28: syntax error near unexpected token `<'
function_return.sh: line 28: `    done < <(echo 1 2 3)'
[mlf4aiur@4aiur Shell]$

using bash run it

[mlf4aiur@4aiur Shell]$ bash function_return.sh 
subshell: inside 1
subshell: inside 0
subshell: outside return 0 var=0
foo: inside 1
foo: outside return 1 var=1
bar: inside 1
bar: outside return 1 var=1
[mlf4aiur@4aiur Shell]$

February 10th, 2012

Mac OS X 贴士汇聚

No Comments, MacOSX, by 4Aiur, 218 views.

# Mac OS X tips

Find & Scan Wireless Networks from the Command Line in Mac OS X

sudo ln -s /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport /usr/sbin/airport
airport -s

Reindexing Spotlight from the Command Line

Reindexing Spotlight from the command line is done with the mdutil tool, first launch Terminal and then type:

sudo mdutil -E /

This will reindex every mounted volume on the Mac, including hard drives, disk images, external drives, etc. Specific drives can be chosen by pointing to them in /Volumes/, to only rebuild the primary Macintosh HD:

sudo mdutil -E /Volumes/Macintosh\ HD/

To reindex an external drive named “External” the command would be:

sudo mdutil -E /Volumes/External/

Use of the mdutil command will spin up mds and mdworker processes as Spotlight goes to work.

Individually Reindexing Selected Files In rare cases, Spotlight can miss a file during index, so rather than reindex an entire drive you can also manually add an individual file to the search index with the mdimport command:

mdimport /path/to/file

The mdimport command can be used on directories as well.

Convert a DMG file to ISO

hdiutil convert /path/imagefile.dmg -format UDTO -o /path/convertedimage.iso

Convert an ISO file to DMG format

hdiutil convert /path/imagefile.iso -format UDRW -o /path/convertedimage.dmg

Set a Zip Password in Mac OS X

zip -e archivename.zip filetoprotect.txt
unzip filename.zip

How to Remove Apps from Launchpad in Mac OS X

  1. Using Launchpad — Mac App Store apps only
    Hold down the Option key, and once the icons start jiggling click the “X” shown in the corner of icons that you want to delete. This removes the app from Launchpad, and does not uninstall them, but this is limited to apps installed from the Mac App Store. If you want to remove an app not installed through the Mac App Store, you have to use the method below:

  2. Using the Terminal — removes any application
    Launch the Terminal and enter the following command, replacing “APPNAME” with the name of the application you want to remove from Launchpad:

run command:

sqlite3 ~/Library/Application\ Support/Dock/*.db "DELETE from apps WHERE title='APPNAME';" && killall Dock

files system usage

sudo fs_usage -f filesys | grep -vE 'iTerm|X11|Xquartz|grep|syslogd'

Mac OS X 系统更新升级包下载后的存储位置,避免多台苹果电脑重复下载

打开 Finder,在顶部菜单栏点击 “前往”,在下拉菜单里选择 “前往文件夹…”,粘入下面这个路径,回车。
看到苹果电脑 Mac OS X 系统更新升级包了吧。
/library/updates

注意,上面这些操作的前提是:下载完系统升级包后别立刻安装,否则安装、重启后,Mac 会自动删除它们。

Stop Lion from Re-Opening Old Windows with Command+Option+Q

chflags nohidden ~/Library/
defaults write com.macromates.textmate NSQuitAlwaysKeepsWindows -bool NO

Access and Use Emoji in Mac OS X Lion

From almost any Mac OS X Lion app, select the “Edit” menu and pull down to “Special Characters”, or hit Command+Option+T

Turn web proxy on/off in Mac OS X Terminal

To turn the proxy off, use:

alias proxyon='networksetup -setwebproxystate Airport on; networksetup -setsecurewebproxystate Airport on'
alias proxyoff='networksetup -setwebproxystate Airport off; networksetup -setsecurewebproxystate Airport off'

You may need change Airport to the appropriate network service. To list the available network services, use this command:

networksetup -listallnetworkservices

Get CPU Info via Command Line in Mac OS X

system_profiler | grep Processor
sysctl -n machdep.cpu.brand_string

Change the terminal window title

name=`hostname`
echo -n -e "\033]0;$name\007"
title () { title=$1; echo -n -e "\033]0;$title\007" }

Convert a Text File to RTF, HTML, DOC, and more via Command Line

textutil -convert filetype filename
textutil -cat rtf file1.txt file2.txt file3.txt -output combinedFiles.rtf

Renewing a DHCP lease

sudo ipconfig set en0 DHCP
sudo ifconfig en0 down ; sudo ifconfig en0 up

easily strace all your apache processes

ps -C apache o pid= | sed 's/^/-p /' | xargs strace
ps auxw | grep sbin/apache | awk '{print"-p " $2}' | xargs strace
ps auxw|grep bin/apache | awk '{print $2":"$10}'|awk -F ':' ' {print "-p "$1}'|xargs strace

a simple interactive tool to convert Simplified Chinese (typed by pinyin) to Traditional Chinese 简繁中文转换

echo "Simplied Chinese:"; while read -r line; do echo "Traditional Chinese:"; echo $line | iconv -f utf8 -t gb2312 | iconv -f gb2312 -t big5 | iconv -f big5 -t utf8; done

Changing Hostname on Mac OS X

sudo scutil --set HostName MY_NEW_HOSTNAME

keep ssh conniction alive

/private/etc/ssh_config
    ServerAliveInterval 60
    ServerAliveCountMax 3

/private/etc/sshd_config
    ClientAliveInterval 60
    ClientAliveCountMax 3

Flush DNS cache

dscacheutil -flushcache

Get DNS Server IP Addresses from the Command Line in Mac OS X

networksetup -getdnsservers airport

Command line MP3 player in Mac OS X

afplay audiofile.mp3

Take a Screenshot with iPhone

Taking a screenshot using an iPhone, iPod touch, or iPad is really easy. All you need to do is:

Hold down the Power button and Home button simultaneously

When the screen flashes, a screenshot has taken

隐藏文件的不同方式

有如其他Unix,你可以在文件名前加上”.”来使其隐藏,例如 /.vol。

这在Finder中是有效的,不过在”ls -a”时却会显示出来。

Mac OS X使用根目录的 .hidden 文件管理需要在Finder中隐藏的文件列表。

同样,HFS+(Mac OS的文件系统)文件和目录可以有一个隐藏属性,通过SetFile命令来设置,SetFile -a V <filename>

你也可以关闭隐藏 属性,通过SetFile -a v <filename>

查看SetFile的man手册了解更多,注意拥有隐藏属性的文件只是在Finder中隐藏,而ls命令仍然可以看到。

设置自动代理

设置Network Preference中AirPort中的Automatic Proxy Configuration

选择proxy.pac后restart AirPort。

命令行打开关闭网卡命令

networksetup -setairportpower en1 off
networksetup -setairportpower en1 on

Twitter for Mac RT

defaults write com.twitter.twitter-mac QuoteTweetSyntax -string 'RT @{USERNAME}: {TEXT}'

Lock the Mac OS X Desktop

  1. shift+ctrl+reject
  2. via Menu Bar
    Launch “Keychain Access”, open Preferences, Select the checkbox next to “Show Status in Menu Bar”
  3. 另外一个方法就是设置Expose属性,在Active Screen Corners中找一个顺手的位置选择Put Display to Sleep,以后鼠标移动到那个角落就可以锁定屏幕了

删除菜单栏的图标

我们精彩会发现菜单栏右上角有些图标是我们用不到的,那些可能是系统自带的,也可能是一些安装程序的默认设置, 按住command直接用鼠标把上面的图标从菜单栏拖下来即可。

How to Remove Icons from the Menu Bar in Mac OS X

holding down the Command key and dragging items out of the menu

快速使用Google搜索

只要是Cocoa程序, 你都可以选择一些文字然后按Shift+Command+L快速以Google搜索。(在Safari中试试看)

quickly access System Preferences

If you want to quickly access the Mac OS X System Preferences, you can do so by holding down the Option key and then hitting various function keys. Option+Brightness pulls up the Display preference pane, Option+Expose brings up the Expose preferences, Option+Volume controls bring up the Sound preferences, and so on.

Mac OS X keyboard shortcuts

  • 关机、重启、休眠

    • Command+Control+Eject – 重启
    • Control+Optionion+苹果键+Eject – 关机
    • Optionion+苹果键+Eject – 休眠
    • Control+Eject – 提示关机、重启或者休眠
  • Startup keyboard shortcuts

    • Option – Display all bootable volumes (Startup Manager)
    • Shift – Perform Safe Boot (start up in Safe Mode)
    • C – Start from a bootable disc (DVD, CD)
    • T – Start in FireWire target disk mode
    • N – Start from NetBoot server
    • X – Force Mac OS X startup (if non-Mac OS X startup volumes are present)
    • Command-V – Start in Verbose Mode
    • Command-S – Start in Single User Mode
  • 截屏

    • Command (⌘)-Shift-3 – 抓取全部屏幕
    • Command (⌘)-Shift-4 – 抓取部分屏幕
  • Optionion+Command (⌘)+D – 隐藏DOCK

  • Optionion+Command (⌘)+Escape – 强制退出应用程序
  • shift+alt+音量调控键 – 微调音量。
  • 文本编辑选中不连贯部分 快捷键:Shift-Command-拖拽
    在文本编辑中,有一个非常有用的技巧,可以让你同时选中文本中多个不连接的部分
    实现这个功能其实很简单,只要在选择文本的时候按住Shift-Command进行拖拽就可以了。
    通过这个功能,我们可以对文本中多个不连接的部分同时进行操作,大大节省了我们的时间。
    通过试验,这个功能不仅仅只在“文本编辑”应用中可以使用,在Pages,Smultron等文本编辑器中都有这个功能。
    所以,下次你用在编辑文本的时候,可以试试这个小功能,看它能不能帮助你提高效率 :-)

References

January 19th, 2012

Setup Workspace On Mac OS X Lion

No Comments, MacOSX, by 4Aiur, 306 views.

# Setup Workspace On Mac OS X Lion

Software Update

Click Apple () menu, choose Software Update

Change System Preferences

Click Apple () menu, choose System Preferences

  1. Trackpad
    Tap to click
    Scroll direction: natural
  2. Mouse
    Adjust Tracking Speed to max
  3. Keyboard
    Keyboard Shortcuts
    Full Keyboard Access: In windows and dialogs, press Tab to move keybiard focus between: –> select “All controls”
  4. Dock
    Magnification
    Change Size and Magnification
    Automatically hide and show the Dock
  5. Mission Control
    Show Dashboard as a space
    Change Show Dashboard shortcut to F4
  6. Language & Text
    Input Sources –> Chinese – Simplified –> Pinyin – Simplified
    Change Input source shortcuts to ^Space
  7. Sound
    Remove “Show volume in menu bar”
  8. Security & Privacy
    Choose “Disable restarting to Safari when screen is locked”
  9. Sharing
    Change your “Computer Name”
  10. Time Machine
    Remove “Show Time Machine status in menu bar”

Dashboard Widgets

  • Dictionary
    For Chinese:
    Install DictUnifier, and import dictionary: stardict-langdao-ec-gb-2.4.2.tar.gz, and drag “stardict-langdao-ec-gb-2.4.2.tar.bz2″ into DictUnifier.
    Now setup Dictionary Preferences, change the dicionary order.
  • iSTAT NANO
    An advanced system monitor in a tiny package. iStat nano is a stunning system monitor widget with beautifly animated menus and transitions.
    Download Page
  • To Do
    A lightweight and fast widget to manage tasks. Thanks to Mac OS X Leopard it integrates with iCal and Mail. The big advantage: to manage your tasks you don’t have to leave these applications open.
    Download Page

Adjust System

  1. Finder
    View –> Show Path Bar, Show Status Bar
    Press “CMD + ,” setup Finder Preferences.
    General –> “New Finder windows show:” –> User’s Home Directory
    Sidebar –> Add your home dir, and remove “All My Files”, “Music”, “Pictures”, “Hard disks”…
    Advanced –> unselect “Empty Trash securely”, When performing a search –> Search the Current Folder
  2. Safari
    Goto YouTuBe, Click “Download Adobe Flash Player from Adobe”, and install it.
    View –> Show Path Bar, Show Status Bar
    Press “CMD + ,” setup Finder Preferences.
    Tabs –> Open pages in tabs instead of windows: Always
    Extensions –> Get Extensions –> Install “AdBlock”, “ClickToFlash”
    Advanced –> “Never use font sizes smaller than: 12″
  3. Mail
    Add new account, and add yourself rules in Mail’s Preferences.
  4. sudoers
    $ sudo vi visudo
    # Uncomment to allow people in group wheel to run all commands
    %wheel ALL=(ALL) ALL
  5. 5.

Install Software

  • App Store
  • Manually

From App Store

Sign in

Using Apple ID sign in, or create new Apple ID.

Install Software

  • Xcode
  • Caffeine
  • Skitch
  • Evernote
  • TextWrangler
  • Opus Domini
  • Window Tidy
  • Twitter
  • The Unarchiver
  • MindNode
  • SketchBook Express
  • 1Password

Manually

  • Adium
    Adium is a free instant messaging application for Mac OS X that can connect to AIM, MSN, Jabber, Yahoo, and more.
    WebSite
  • AppCleaner
    AppCleaner is a small application which allows you to thoroughly uninstall unwanted apps.
    WebSite
  • GitHub
    GitHub is the best way to collaborate with others. Fork, send pull requests and manage all your public and private git repositories.
    Download page
  • iTerm2
    iTerm2 is a replacement for Terminal and the successor to iTerm. It works on Macs with Leopard, Snow Leopard, or Lion. Its focus is on performance, internationalization, and supporting innovative features that make your life better.
    Download page
  • MPlayer OSX Extended
    MPlayer OSX Extended is the future of MPlayer OSX. Leveraging the power of the MPlayer and FFmpeg open source projects, MPlayer OSX Extended aims to deliver a powerful, functional and no frills video player for OSX.
    Download page
  • Sequel Pro
    Sequel Pro is a fast, easy-to-use Mac database management application for working with MySQL databases.
    Download page
  • FireFox
    Download page
  • TextMate2
    TextMate brings Apple’s approach to operating systems into the world of text editors. By bridging UNIX underpinnings and GUI, TextMate cherry-picks the best of both worlds to the benefit of expert scripters and novice users alike.
    WebSite
  • Sublime Text 2
    Sublime Text is a sophisticated text editor for code, html and prose. You’ll love the slick user interface and extraordinary features.
    WebSite
  • Skype
    WebSite
  • Chicken of the VNC
    Chicken of the VNC is a VNC client for Mac OS X. A VNC client allows one to display and interact with a remote computer screen. In other words, you can use Chicken of the VNC to interact with a remote computer as though it’s right next to you.
    Download page
  • MacPorts
    The MacPorts Project is an open-source community initiative to design an easy-to-use system for compiling, installing, and upgrading either command-line, X11 or Aqua based open-source software on the Mac OS X operating system.
    Download page

Command Line

vim

curl -O "ftp://ftp.vim.org/pub/vim/unix/vim-7.3.tar.bz2"
tar jxf vim-7.3.tar.bz2
cd vim73
./configure --enable-pythoninterp --enable-rubyinterp
make && sudo make install

port

sudo port selfupdate
sudo port -c install wget@ssl
sudo port -c install axel
sudo port -c install gsed
sudo port -c install nmap

pip

# Install pip
sudo easy_install-2.7 pip
# Install python libraries
# ipython - IPython: Productive Interactive Computing
sudo pip-2.7 install ipython
# Mercurial - Fast scalable distributed SCM (revision control, version control) system
sudo pip-2.7 install Mercurial
# pep8 - Python style guide checker
sudo pip-2.7 install pep8
# flake8 - code checking using pep8 and pyflakes
sudo pip-2.7 install flake8
# pyflakes - passive checker of Python programs
sudo pip-2.7 install pyflakes
# ropevim- A vim plugin for using rope python refactoring library
sudo pip-2.7 install ropevim
# paramiko                  - SSH2 protocol library
sudo pip-2.7 install paramiko

RVM

bash -s stable < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer )
# Load RVM by appending the rvm function sourcing to your .bash_profile:
echo '[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm" # Load RVM function' >> ~/.bash_profile

.bash_profile

cat >> ~/.bash_profile <<\EOF
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
alias ls='ls -G'
alias ll='ls -lG'
alias vi='/usr/local/bin/vim'
alias grep='grep --color'
alias Github='cd ~/Documents/workspace/Github/'
alias cgiserver="ifconfig | grep --color -o "inet 1[079][^ ]*"; python -m CGIHTTPServer 8000" # cgi_directories ['/cgi-bin', '/htbin']
alias webshare='share () { port=$1; ifconfig | grep --color -o "inet 1[079][^ ]*"; python -m SimpleHTTPServer ${port:-8000} ;}; share'
title () { title=$@; echo -n -e "\033]0;${title}\007"; }

export LSCOLORS=ExGxCxDxCxEgEdAbAgAcAd
export PS1='[\u@\h \W]\$ '

export LANGUAGE=en_US.UTF-8
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8

shopt -s histappend
PROMPT_COMMAND="history -a; "
HISTTIMEFORMAT="%F %T "
HISTSIZE=2000
export HISTTIMEFORMAT
export PATH=/opt/local/bin:/opt/local/sbin:$PATH
EOF

Adjust your Dock

Remove your application not very often, and add your favorite applications into Dock.

Applications Tips

MacPorts

# Search software
port search vim
# Install software
port install wget@ssl
sudo port -d selfupdate
sudo port -v selfupdate
port outdate
sudo port -c -u upgrade outdated
port installed

pip

# search: Search PyPI
pip search pep8
#install: Install packages
pip install pep8
#uninstall: Uninstall packages
pip uninstall pep8

RVM

# Display a list of all "known" rubies. NOTE: RVM can install many more Rubies not listed.
rvm list known
# Install a version of Ruby (eg 1.9.3):
rvm install 1.9.3
# Use the newly installed Ruby:
rvm use 1.9.3
# Check this worked correctly:
ruby -v
which ruby
# Optionally, you can set a version of Ruby to use as the default for new shells. Note that this overrides the 'system' ruby:
rvm use 1.9.3 --default

Binding Multiple IP Addresses on the Same Network Interface

Add new address

sudo ifconfig en1 alias 192.168.2.2 netmask 255.255.255.0
sudo ifconfig en1 alias 192.168.3.3 netmask 255.255.255.0
sudo ifconfig en1 alias 192.168.4.4 netmask 255.255.255.0
sudo ifconfig lo0 alias 127.0.0.2

Remove alias address

sudo ifconfig en1 remove 192.168.2.2 netmask 255.255.255.0
sudo ifconfig en1 192.168.3.3 netmask 255.255.255.0 delete
sudo ifconfig en1 192.168.4.4 netmask 255.255.255.0 -alias
sudo ifconfig lo0 -alias 127.0.0.2

January 10th, 2012

Installing Logster on CentOS

No Comments, SysAdmin, by 4Aiur, 167 views.

# Installing Logster on CentOS

Install EPEL repository

sudo rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-6.noarch.rpm
yum update # This takes quite a while for a fresh install

Setting locale

cat >> ~/.bash_profile << EOF
export LANGUAGE=en_US.UTF-8
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
EOF
source .bash_profile

Install Dependence

yum -y install logcheck

logcheck dependencies:

  • liblockfile
  • lockfile-progs
  • perl-IPC-Signal
  • perl-Proc-WaitStat
  • perl-mime-construct

Install logster

git clone git://github.com/etsy/logster.git
cd logster
make install

dry run

/usr/sbin/logster --output=stdout SampleLogster /var/log/httpd/access_log

Add crontab

crontab -e
* * * * * /usr/sbin/logster -p blog_4aiur_net --output=graphite --graphite-host=localhost:2003 SampleLogster /var/log/httpd/blog.4aiur.net_access_log >/dev/null 2>&1

January 10th, 2012

Installing and Configuring Graphite on CentOS

No Comments, SysAdmin, by 4Aiur, 329 views.

# Installing and Configuring Graphite on CentOS

Install EPEL repository

rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-5.noarch.rpm
yum update # This takes quite a while for a fresh install

Install Dependences

yum install -y pycairo mod_python Django python-ldap python-memcached python-sqlite2 \
    bitmap bitmap-fonts python-devel python-crypto pyOpenSSL zope gcc

Install Twisted

wget http://pypi.python.org/packages/source/T/Twisted/Twisted-11.1.0.tar.bz2
tar jxf Twisted-11.1.0.tar.bz2
pushd Twisted-11.1.0
python setup.py install
popd
rm -rf Twisted-11.1.0*

Install Python package management software

wget http://peak.telecommunity.com/dist/ez_setup.py
python ez_setup.py
easy_install pip

Install Graphite

# a Twisted daemon that listens for time-series data
pip install carbon
# a simple database library for storing time-series data (similar in design to RRD)
pip install whisper
pip install django
pip install django-tagging
# A Django webapp that renders graphs on-demand using Cairo
pip install graphite-web

Configure graphite

cd /opt/graphite/conf
rename .conf.example .conf *
cd /opt/graphite/webapp/graphite
python manage.py syncdb
chown -R apache:apache /opt/graphite/storage/

Start the data collection daemon carbon-cache

# cd /opt/graphite/bin
# python carbon-cache.py start

Configure Apache VirtualHost

<VirtualHost *:80>
    ServerName graphite.4aiur.net
    DocumentRoot "/opt/graphite/webapp"
    CustomLog /var/log/httpd/graphite.4aiur.net_access_log combined
 
    <Location "/">
        SetHandler python-program
        PythonPath "['/opt/graphite/webapp'] + ['/usr/lib/python/site-packages/'] + sys.path"
        PythonHandler django.core.handlers.modpython
        SetEnv DJANGO_SETTINGS_MODULE graphite.settings
        PythonDebug Off
        PythonAutoReload Off
    </Location>
 
    <Location "/content/">
        SetHandler None
    </Location>
 
    <Location "/media/">
        SetHandler None
    </Location>
    alias /media/ /usr/lib/python/site-packages/django/contrib/admin/media/
</VirtualHost>

Test insert data to graphite

run test

python example-client.py

example-client.py source code

import sys
import time
import os
import platform
import subprocess
from socket import socket
 
CARBON_SERVER = '127.0.0.1'
CARBON_PORT = 2003
delay = 60 
if len(sys.argv) > 1:  
    delay = int( sys.argv[1] )
 
def get_loadavg():    
    # For more details, "man proc" and "man uptime"      
        if platform.system() == "Linux":
            return open('/proc/loadavg').read().strip().split()[:3]    
        else:
            command = "uptime"
            process = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True)                      
            os.waitpid(process.pid, 0)
            output = process.stdout.read().replace(',', ' ').strip().split()          
            length = len(output)
            return output[length - 3:length]
 
 
sock = socket()
try:
    sock.connect((CARBON_SERVER,CARBON_PORT))
except:
    print "Couldn't connect to %(server)s on port %(port)d" % {'server':CARBON_SERVER, 'port':CARBON_PORT}
    sys.exit(1)
 
while True:
    now = int( time.time() )
    lines = []
    # We're gonna report all three loadavg values
    loadavg = get_loadavg()
    lines.append("system.loadavg_1min %s %d" % (loadavg[0],now))    
    lines.append("system.loadavg_5min %s %d" % (loadavg[1],now))    
    lines.append("system.loadavg_15min %s %d" % (loadavg[2],now))    
 
    message = '\n'.join(lines) + '\n' 
    #all lines must end in a newline
    print "sending message\n"
    print '-' * 80
    print message
    print
    sock.sendall(message)
    time.sleep(delay)

View graphite data

service httpd restart

goto your graphite site

Delete graphite data

cd /opt/graphite/storage/whisper
rm your_data.wsp

January 9th, 2012

JMX monitoring

1 Comment, Default, by 4Aiur, 202 views.

# JMX monitoring

dataflow

java app -> jmxagent ->
                         jmxtrans -> jmx_output.log -> alert.sh -> send mail
java app -> jmxagent ->

Configuration jmx agent with authentication

JMX dynamically allocated random port, and it will bind the port at internal address. If you connecting jmx through firewall or your servers on Amazon EC2, maybe can’t connect to the jmx agent, So need to do some prepare.

add jmx agent parameter in your java startup script

cmd[0]='curl -s http://ifconfig.me/ip 2>/dev/null | tr -d "\n"'
cmd[1]='curl -s http://sputnick-area.net/ip 2>/dev/null'
for ((x=0; x<${#cmd[@]}; x++))
do
    tmp=$(echo ${cmd[$x]} | sh)
    if echo $tmp | grep -q "^\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}$"; then
        external_ip=$tmp
        break
    fi
done
-Drmi.agent.port=1234 -javaagent:/opt/app/plugins/jmx-agent.jar \
-Djmx.remote.x.password.file=/opt/app/conf/jmxremote.password \
-Djmx.remote.x.access.file=/opt/app/conf/jmxremote.access \
-Djava.rmi.server.hostname=${external_ip:-127.0.0.1}

configuration jmx authentication

cat > /opt/app/conf/jmxremote.access << EOF
monitor   readonly
EOF
cat > /opt/app/conf/jmxremote.password << EOF
monitor  yourmonitoringaccesspassword
EOF
chmod 600 /opt/app/conf/jmxremote.access /opt/app/conf/jmxremote.password

build JMXAgent.class to jmx-agent.jar

package example.rmi.agent;
 
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.rmi.registry.LocateRegistry;
import java.util.HashMap;
 
import javax.management.MBeanServer;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
 
/**
 * This class is used for the resolve the
 * "Connecting Through Firewall Using JMX" issue.
 * 
 * http://blogs.oracle.com/jmxetc/entry/connecting_through_firewall_using_jmx
 * 
 * @author root
 * 
 */
public class JMXAgent {
 
 
	private static int _rmiRegistryPort=3000;
 
 
 
	public static void premain(String agentArgs) throws IOException {
 
		// Ensure cryptographically strong random number generator used
		// to choose the object number - see java.rmi.server.ObjID
		//
		System.setProperty("java.rmi.server.randomIDs", "true");
 
		// Start an RMI registry on port specified by example.rmi.agent.port
		// (default 3000).
		//
		final int port = Integer.parseInt(System.getProperty(
				"yottaa.rmi.agent.port", String.valueOf(_rmiRegistryPort)));
 
		System.out.println("Create RMI registry on port " + port);
		LocateRegistry.createRegistry(port);
 
		// Retrieve the PlatformMBeanServer.
		//
		System.out.println("Get the platform's MBean server");
		MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
 
		// Environment map.
		//
		System.out.println("Initialize the environment map");
		HashMap<String, Object> env = new HashMap<String, Object>();
 
		// This where we would enable security - left out of this
		// for the sake of the example....
		//
 
		// Create an RMI connector server.
		//
		// As specified in the JMXServiceURL the RMIServer stub will be
		// registered in the RMI registry running in the local host on
		// port 3000 with the name "jmxrmi". This is the same name the
		// out-of-the-box management agent uses to register the RMIServer
		// stub too.
		//
		// The port specified in "service:jmx:rmi://"+hostname+":"+port
		// is the second port, where RMI connection objects will be exported.
		// Here we use the same port as that we choose for the RMI registry.
		// The port for the RMI registry is specified in the second part
		// of the URL, in "rmi://"+hostname+":"+port
		//
		System.out.println("Create an RMI connector server");
		final String hostname = InetAddress.getLocalHost().getHostName();
		JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://" + hostname
				+ ":" + port + "/jndi/rmi://" + hostname + ":" + port
				+ "/jmxrmi");
 
		// Now create the server from the JMXServiceURL
		//
		JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
 
		// Start the RMI connector server.
		//
		System.out.println("Start the RMI connector server on port " + port);
		cs.start();
	}
 
}

Install jmxtrans on your alert server

rpm -Uvh http://jmxtrans.googlecode.com/files/jmxtrans-250-0.noarch.rpm
ln -s /usr/java/jdk1.6.0_27/bin/jps /usr/bin/jps

Configuration jmxtrans

cat > /var/lib/jmxtrans/monitoring.json << \EOF
{
    "servers": [
        {
            "host": "hostA", 
            "port": "1234", 
            "username": "monitor", 
            "password": "yourmonitoringaccesspassword", 
            "numQueryThreads": 2, 
            "queries": [
                {
                    "attr": [
                        "HeapMemoryUsage", 
                        "NonHeapMemoryUsage"
                    ], 
                    "obj": "java.lang:type=Memory", 
                    "output.jsontWriters": [
                        {
                            "@class": "com.googlecode.jmxtrans.model.output.jsont.KeyOutWriter", 
                            "settings": {
                                "debug": true, 
                                "maxLogBackupFiles": 3, 
                                "maxLogFileSize": "10MB", 
                                "output.jsontFile": "/var/log/jmxtrans/jmx_output.log", 
                                "typeNames": ["name"]
                            }
                        }
                    ]
                }
            ]
        }, 
        {
            "host": "hostB", 
            "port": "1234", 
            "username": "monitor", 
            "password": "yourmonitoringaccesspassword", 
            "numQueryThreads": 2, 
            "queries": [
                {
                    "attr": [
                        "HeapMemoryUsage", 
                        "NonHeapMemoryUsage"
                    ], 
                    "obj": "java.lang:type=Memory", 
                    "output.jsontWriters": [
                        {
                            "@class": "com.googlecode.jmxtrans.model.output.jsont.KeyOutWriter", 
                            "settings": {
                                "debug": true, 
                                "maxLogBackupFiles": 3, 
                                "maxLogFileSize": "10MB", 
                                "output.jsontFile": "/var/log/jmxtrans/jmx_output.log", 
                                "typeNames": ["name"]
                            }
                        }
                    ]
                }
            ]
        }
    ]
}
EOF

Running Jmx Transformer

service jmxtrans start
# or run jmxtrans manually
cd /usr/share/jmxtrans/
/usr/share/jmxtrans/jmxtrans.sh start /var/lib/jmxtrans/monitoring.json
/usr/share/jmxtrans/jmxtrans.sh stop /var/lib/jmxtrans/monitoring.json

View jmxtrans log

cd /var/log/jmxtrans
tailf jmxtrans.log

Alert script thresholds config

cat > thresholds.conf << EOF
#parttern expression value
\.\.HeapMemoryUsage_used Maximum 2500000000
\.\.HeapMemoryUsage_committed Minimum 6000000000
EOF

Alert script

cat > /opt/alert.sh << \EOF
#!/usr/bin/env bash
 
# configs
source_file="/var/log/jmxtrans/jmx_output.log"
max_line=500
now=$(date +%s)
expire=61
to_addr="your@email.address"
TAC="/usr/bin/tac"
 
# functions
logger () {
    datetime=$(date +"%F %T")
    echo ${datetime}: $*
}
 
send_mail () {
    message=$*
    logger send email
    logger $message
    #echo $message | mail -s "jmx alert" ${to_addr}
}
 
# main 
logger "start."
message=$($TAC $source_file 2>/dev/null | head -${max_line} | \
    awk -v Now=$now -v Expire=$expire '
BEGIN{
    # configuration
    # #parttern expression value
    # HeapMemoryUsage_used Maximum 2500000000
    # HeapMemoryUsage_committed Minimum 6000000000
    while (getline < "thresholds.conf") {
        if ($0 ~ "#") {
            continue
        } else {
            Partterns[$1] = $1
            Expressions[$1] = $2
            Values[$1] = $3
        }
    }
}
# input: hostA_1234.sun_management_MemoryImpl..HeapMemoryUsage_used 734907264   1325840738049
function scanner (Attr, Value) {
    for (Parttern in Partterns) {
        if (Attr ~ Parttern) {
            if (Expressions[Parttern] == "Maximum") {
                if (Value >= Values[Parttern]) {
                    return Hit=1
                }
            } else if (Expressions[Parttern] == "Minimum") {
                if (Value <= Values[Parttern]) {
                    return Hit=1
                }
            }
        }
    }
    return Hit=0
}
{
    if (NF!=3) {
        next
    } else {
        Attr = $1
        Value = $2
        TimeStamp = int($3/1000)
        if ((TimeStamp+Expire) >= Now) {
            scanner(Attr, Value)
            if (Hit == 1) {
                print
                exit
            }
        } else {
            exit
        }
    }
}
')
 
if [[ ! -z $message ]]; then
    send_mail "$message"
fi
logger "done."
EOF
chmod +x /opt/alert.sh

Add script into crontab

crontab -l > tmp.cron
echo "* * * * * /opt/alert.sh >> /var/log/jmxtrans/alert.log 2>&1" >> tmp.cron
crontab tmp.cron
rm -f tmp.cron

References

December 26th, 2011

Suppressing paramiko log

No Comments, Python, by 4Aiur, 126 views.

Suppressing paramiko log

Backup paramiko source file.

cd /usr/local/lib/python2.7/site-packages/
cp -p paramiko/util.py{,.bak}

Modify paramiko/util.py.

diff paramiko/util.py{,.bak}
 
265c265
<         return not (record.name == 'suppress' and record.levelname == 'INFO')
---
>         return True

Set logger name “suppress” in your code.

self.client = SSHClient()
self.client.set_log_channel('suppress')

December 16th, 2011

Zenoss Core setup guide

No Comments, SysAdmin, by 4Aiur, 282 views.

# Zenoss Core setup guide

Zenoss Core is a powerful monitoring system, and it is a OpenSource software.

Install Zenoss Core
Install ZenPacks
Setup snmp and snmpd config
Add user command
Add a single device
Add custom Device Class
Custom new class properties
Setup Processes
Custom Zenoss reports

Install Zenoss Core

Before you install:

1) Run the Yellowdog Updater, Modified (YUM), which you will use to install Zenoss. To run YUM, enter this command:

# yum -y install mysql-server.x86_64 mysql-devel.x86_64 net-snmp.x86_64 \
        net-snmp-utils.x86_64 gmp.x86_64 libgomp.x86_64 libgcj.x86_64 \
        liberation-fonts.noarch sysstat.x86_64 fping.x86_64

2) Download the Zenoss installation files.

# mkdir /opt/package
# cd /opt/package
# wget "http://downloads.sourceforge.net/project/zenoss/zenoss-3.2/zenoss-3.2.0/zenoss-3.2.0.el5.x86_64.rpm"

3) If you have just installed MySQL, then use the following command to add MySQL into the startup sequence:

# /sbin/chkconfig --add mysqld

4) Enter the following command to display current run levels:

# /sbin/chkconfig --list mysqld

5) If the system responds with something similar to:

mysqld 0:off 1:off 2:off 3:off 4:off 5:off 6:off

then enter the following command to adjust run levels:

# /sbin/chkconfig --level 2345 mysqld on

6) Restart MySQL and set the password.

Note:
    Do not add a space between the single quotes in the following commands.

# /etc/init.d/mysqld restart
# /usr/bin/mysql_secure_installation
# /usr/bin/mysqladmin -u root password ''
# /usr/bin/mysqladmin -u root -h localhost password ''

Note:
    Initially, the MySQL password must be blank so that Zenoss can correctly create the database. After you have installed and started Zenoss, you can change this password.

Install the Software

Follow these steps to install Zenoss for Red Hat Enterprise Linux 5 or CentOS 5.

1) Enter one of the following commands to install the Zenoss RPM.

# rpm -ivh zenoss-3.2.0.el5.x86_64.rpm

2) If MySQL is running on a different server, or has a different root user password, edit the /opt/zenoss/bin/ zenoss_init_pre file and adjust the MYSQLHOST, MYSQLROOTUSER, and MYSQLROOTPASSWD values.

3) Enter this command to start Zenoss.

# service zenoss start

Note:
    This step may take several minutes.

Install ZenPacks

Setup snmp and snmpd config

add snmp.conf to zenoss server /etc/snmp/snmp.conf. snmp.conf example:

defversion 3
defsecurityname yourname
defsecuritylevel authNoPriv
defauthtype MD5
defauthpassphrase yourpassword

add snmpd.conf to client /etc/snmp/snmpd.conf. snmpd.conf example:

createUser yourname MD5 "yourlonglonglonglongpassword" DES
rouser yourname auth -V yourview
 
#                     sec.model    sec.name
group monitorGroup    usm         yourname
 
#       name          incl/excl    subtree         mask(optional)
view    yourview    included     .1.3.6.1.2.1
view    yourview    included     .1.3.6.1.4.1
 
#       group         context sec.model sec.level prefix read       write  notif
access  monitorGroup  ""      any       auth      exact  yourview none none
 
syslocation Undefined
syscontact NOC <noc@unknown.com>
 
# "Pass-through" MIB extension command
pass .1.3.6.1.4.1.2021.255 /usr/share/doc/net-snmp-5.3.2.2/passtest</noc>

Add user command for debug snmp setting

  1. Go to http://yourhost:8080/zport/dmd/dataRootManage
  2. Click “Add User Command”
  3. Input value
Name: snmpwalkV3
Description: snmpwalk using version 3
Command: snmpwalk -${device/zSnmpVer} -l authNoPriv -u ${device/zSnmpSecurityName} -A ${device/zSnmpAuthPassword} -a ${device/zSnmpAuthType} ${here/manageIp} system

Add a single device

  • Go to http://yourhost:8080/zport/dmd/itinfrastructure
  • Click “Add a Single Device”
    Add_a_Single_Device-1
  • Input items
    Add_a_Single_Device-2
  • Click “Zenoss Server”, and Click left “Configuration Properties” to edit the server’s properties
    • zSnmpVer: v3
    • zSnmpSecurityName: yourname
    • zSnmpAuthPassword: yourlonglonglonglongpassword
    • zSnmpAuthType: MD5
  • Click “Commands –> snmpwalkV3″ verify server and client snmp configuration
  • Click “Actions –> Model Device”

Add custom Device Class

Custom new class properties

Add_Device_Class

using zenoss portal

using zenoss manage and zendmd

1) Login to Zenoss as “admin” and go to the URL http://yourhost:8080/zport/dmd/Devices/manage
2) Click left “your new class name”, and click top “Properties”
3) To add a new property, enter a name, type and value for the new property and click the “Add” button.
Name: zCollectorPlugins
Type: lines

Value:

  • zenoss.snmp.NewDeviceMap
  • zenoss.snmp.DeviceMap
  • zenoss.snmp.InterfaceMap
  • zenoss.snmp.RouteMap
  • zenoss.snmp.IpServiceMap
  • zenoss.snmp.HRFileSystemMap
  • zenoss.snmp.HRSWInstalledMap
  • zenoss.snmp.HRSWRunMap
  • zenoss.snmp.CpuMap

Name: zDeviceTemplates
Type: lines

Value:

  • b_fping
  • Device
  • FileSystem

Name: zIcon
Type: string
Value: /zport/dmd/img/icons/server.png
Name: zSnmpAuthType
Type: string
Value: MD5
Name: zSnmpVer
Type: string
Value: v3

4) Login zendmd, change default snmp auth password

# su - zenoss
$ zendmd
>>> dmd.Devices.yourclassname.zSnmpAuthPassword = 'yourlonglonglonglongpassword'
>>> commit()

Add Custom Schema

Setup Processes

Zenoss API

Zenoss have jsonapi and xmlrpc interface, you can using it’s API to integrate your management system.
jsonapi code demo:

def add_device(self, deviceName, deviceClass, title,
                productionState=1000, model=False):
    data = dict(deviceName=deviceName, deviceClass=deviceClass,
                title=title, productionState=productionState, model=model)
    return self._router_request('DeviceRouter', 'addDevice', [data])

xmlrpc code demo:

def add_device(self, deviceName, devicePath, tag):
    url = 'http://%s:%s@%s/zport/dmd/DeviceLoader' % (self.username,
            self.password, self.zenoss_host)
    serv = ServerProxy(url)
    serv.loadDevice(deviceName, devicePath, tag)

Custom Zenoss Reports

Column syntax

buildin command:

getId

python command:

python:str(dev.getRRDValue('ProcessInfo_FileDescriptor')).split('.')[0]

custom python script:

getMemUtil

Goto http://yourhost:8080/zport/dmd/Devices/manage first.

Custom_Python_Script

Input script name getMemUtil(), and input content like this:

total_memory = context.hw.totalMemory
mem_avail_real = context.getRRDValue('memAvailReal_memAvailReal')
mem_cached = context.getRRDValue('memCached_memCached')
if total_memory and mem_avail_real and mem_cached:
    print '%.2f%%' % ((total_memory - (mem_avail_real + mem_cached) * 1024) / total_memory * 100)
else:
    print('Unknown')
return printed

Send report email

cat <<\EOF > $ZENHOME/scripts/emailSummaryDailyReport.sh
#!/bin/sh
REPORTS_URL="http://yourhost:8080/zport/dmd/Reports/Graph%20Reports/Production/Production%20Summary%20Report/viewGraphReportClean/zport/RenderServer/render?width=500&amp;drange=864000"
$ZENHOME/bin/reportmail \
--user=username \
--passwd= yourlonglonglonglongpassword \
--from="noc@foo.com" \
--address="noc@foo.com" \
--address="ops@bar.com" \
--subject="Zenoss: System Summary Daily Report" \
--url="$REPORTS_URL"
EOF

Add it into crontab

0 20 * * * /opt/zenoss/scripts/emailSummaryDailyReport.sh 2>&1 >/dev/null

References:


.