2012年09月29日

【Linux】文字化けで解凍不能なZIPファイル用「unzip-cp932」初版リリース

 頻度は少ないもののLinux機でZIPファイルを解凍しようとしても、その中の圧縮ファイルのフォルダ名が文字化けしていることが起因となり、結果としてファイルを解凍出来ないことがある。これらは、Windows環境下同士なら問題にならないことなので、日常的にWindows機を利用している人なら取り敢えずはそちらで対処しUSBメモリー等でLinux機に持ってくれば済むことなのだが、当方の様に端末も含めLinux中心に利用している者にとってはとても困ることになる。そんなことで、Ubuntu環境ではcp932のパス名対応のオプションバッチを当てたunzipが存在するものの当方の利用しているCentOS6様のRPMパッケージはない様だったので、Pythonの標準ライブラリのみでcp932対応のunzipもどきを作成して試た。

 ここで公開の「unzip-cp932」はpythonで作成しているので、今時のLinuxであれば初めからpythonはinstallされているので、同名でファイルをコピペで作成後、1行目のpythonのinstall位置を修正し、「chmod +x ./unzip-cp932」でファイルに実行権限を付与とするだけで実行出来る様になる。

 利用法は以下の通りで、画面出力はunzipにいくらか真似て試たが、今の所、コマンドオプションとしては、ZIPファイル名(必須)と解凍先のディレクトリ位置(省略時はカレントディレクトリ)のみを有効としているだけで、オリジナルのunzipとは程遠い点はご勘弁頂きたい。気になる方は、GPLライセンスに従い、思い通りに改善し公開頂きたい。




[mire@localhost ~]$ ./unzip-cp932 /media/HD-PCTX5/2010/03/Photos20100305_from_suzu.zip ~/test_a
filepath: /media/HD-PCTX5/2010/03/Photos20100305_from_suzu.zip
inflating: 霧島登山/集合写真a.jpg
inflating: 霧島登山/集合写真b.jpg
inflating: 霧島登山/20100305/01.jpg
inflating: 霧島登山/20100305/02.jpg
inflating: 霧島登山/20100305/03.jpg
<中略>
inflating: 霧島登山/20100305/12.jpg
inflating: 霧島登山/20100305/MOVIE/01.mp4
inflating: 霧島登山/20100305/MOVIE/02.mp4

[mire@localhost ~]$
 また、最初のコマンド引数としてファイルを指定しなかったり、ヘルプを意図する「--help」や「--hh」を指定した場合には以下の様な説明書きを表示する様にしている。利用方法の確認には、そうして頂きたい。



[mire@localhost ~]$ ./unzip-cp932 --help
unzip-cp932 0.0.1 of 2012-09-28. Maintained by Mire in Japan. Send bug
reports using http://pythonlife.seesaa.net/article/294731873.html

USAGE: unzip-cp932 <a zip file> [<path for extract files into>]

利用方法: unzip-cp932 <zipファイル> [<解凍先ディレクトリ>]

※ 実行には最低で解凍対象のZIPファイル1つを指定する必要があります。
 オプションとして解凍先ディレクトリを続けて指定することが出来ますが、
unzipコマンドの様な多様なオプションは一切実装していませんし、解凍後の
ファイル中の文字コード自体は当前圧縮時のままです。中身のコード変換は
nkf辺りがその守備範囲です。そこらをあたって下さい。
 また、解凍先に解凍ファイルと同じ名のファイルがある場合は、今の所
既存ファイルの上書き喪失を回避する為、同名ファイル解凍しない仕様です。
一つでも「 already exists.」と表示されたなら<解凍先ディレクトリ>に
新規の解凍先名を指定して試て下さい。ZIPの中身全てが解凍出来る筈です。
 尚、これは公開義務等のGPLライセンスを満たす範囲で改良頂けます。
その場合の改変内容公開は不具合連絡同様に下記の当方Blogへのコメントで
済ませて頂いて構いません。
http://pythonlife.seesaa.net/article/294731873.html
[mire@localhost ~]$


 これを実現している「unzip-cp932」のソースコードは以下の通り(但し、最新公開版は次稿の【Linux】文字化けで解凍不能なZIPファイル用「unzip-cp932」第4版リリース)。
続きを読む
posted by Mire at 13:28 | Comment(1) | TrackBack(0) | Pythonプログラミング | このブログの読者になる | 更新情報をチェックする

2012年09月22日

【Matplotlib】温度とFAN回転率解析「ipmiSensor9.py」リリース

 「HP ProLiantサーバー ML110 G7の各温度とFAN回転率推移解析の為に手掛けた「ipmiSensor」作成で必要な「Matplotlib」上の機能について一通り理解出来たので、一つの区切りとして、ここに掲載公開する。
 「Matplotlib」は例えば時系列の副目盛のラベルの回転や、主目盛との併記時の位置合わせ等の様に、オブジェクトに入れ子で包含される個別のインスタンスに対しメソッドを実行することで変更が可能になるものもあり、かゆい処に手が届く様になるには、相応に実行で生成されるインスタンスのクラス構造をマニュアル等で調べ包含されるオブジェクトのメソッドを知ることが不可欠となる。「ipmiSensor.py」では、それらの処理を関数内に組込み、「Matplotlib」の仕様を認識しなくとも、その引数に値を指定するだけで望みの見栄えを追求出来る様に努めている。その仕様は未だ汎用化には程遠い出来だが任意の時系列期間をレンジとして、その期間内に含まれるDB上のデータを折れ線グラフとしてプロットする用途に限定すれば、それ程不自由しない程度にはなったと思う。
 尚、ソースコードの既定の変数を変更せずとも、コマンドオプションとして数値と文字列であれば変数に指定することも出来る。但し、セキュリティ的視点での制限は一切加えていないので今後は適宜変数個別に展開して行く方が望ましいだろう。因みにグラフ化する時系列範囲はstartとendで、凡例の゜配置や列数をl_locationとl_colで指定すると以下の様になる。



[root@www mire]# date; ./ipmiSensor9.py start="2012-09-19 05:55:01" end="2012-09-22 05:55:01" l_col=8 l_location="lower center"
2012年 9月 22日 土曜日 00:13:41 JST
l_col=8
l_location=lower center
HP_ProLiant_ML110_G7_Sensors_Graph_2012-09-19_055501__2012-09-22_001001
2012-09-22 05:55:01
2012-09-19 05:55:01
tm_range= 3 days, 0:00:00
1日〜3日: 1日〜3日: 副目盛は毎時の「時」表示
処理時間: 0:00:03.862130
[root@www mire]#
「HP ProLiant ML110 G7 FANと温度(via ipmi & lm_sensors)」2012-09-19 05:55:01〜2012-09-22 05:55:01

 さて、現状はその程度だが、今後はこの「ipmiSensor.py」のコードは、長期の時系列範囲のグラフは、crondのスクリプトとして定期作成する形で、時々刻々変わる当日分についてはCGIスクリプトとして、Webアクセス時に作成する形で活用することにする。そこで現在は全定義関数を同一ソースコードに置いているが、今後は共通定義分をモジュールとしてsite-packagesに置き、それを各スクリプト側でimportする形の利用となる予定だ。

 「ipmiSensor9.py」のソースコードは以下の通り。(2012-09-22追記: 0.0.9a 凡例背景等の透明度設定を追加した。)
            ~/ipmiSensor9.py (前半)


#!/usr/bin/python2.6
#!/usr/bin/python2.6
#-*- coding: utf-8 -*-
u"""
スクリプト利用
===============

ipmitool sensorで得られるセンサー値をDBにcrondで蓄積、グラフ化


定義関数群
==========

:sensors() : ipmitool sensorで得られるセンサー値を辞書として数値listで返す関数
:prn_sensors() : ipmitool sensorのデータをコンソール出力(sensors()動作check用)
:names_dic() : センサーIDに対する表示名の辞書を返す関数
:query_datas() : DB上のDataを読込む関数
:ins_db() : ipmitool sensor で得られるセンサー値をDBに書込むモジュール
:mk_graph() : DB上のDataをグラフ化する関数
:set_ticks_label(): 目盛ラベルの各種設定値の変更


グラフ化可能な時系列の範囲
==========================

西暦100年1月1日0時〜9900年12月31日23時59分59秒

:datetime.datetime() : 西暦 1年1月1日 〜 9999年12月31日
:datetime.strptime() : 西暦1000年1月1日 〜 9999年12月31日
:自作strptime()関数 : 西暦 1年1月1日 〜 9999年12月31日(未使用)
:Firebird timestamp型: 西暦 100年1月1日 〜 32768年 2月29日
:matplotlib/dates.py : 西暦 100年1月1日 〜 9900年12月31日 """

__author__ = "Mire in Japan"
__date__ = "2012-09-22"
__version__ = '0.0.9a'
__copyright__ = 'Copyright (c) 2012-07-27 Mire'
__license__ = 'GPL'
__url__ = 'http://pythonlife.seesaa.net/article/293580501.html '

__todo__ = u"""
1. 済: 取り敢えず、crondで定期的にDBにぶち込んだデータを取出しグラフ化する初期バージョンを作成
2. 済: DB,pythonコード処理でどの程度速度的に有利かを比較し最適なものを採用: id個別queryとする!!
3. 済: OpenIPMI-python活用によるメリットを探る: ん、探しあてたsampleも動かぬ。深追いせず(笑)。
4. 生成グラフX軸の時系列目盛を期間により多段で変更する様に
5. NET-SNMPの情報活用を附加
6. NET-SNMP-python活用によるメリットを探る
7. RRD的なデータ処理附加の検討
8. Ninoの様なシステム化の可能性を探る"""
__history__ = """
0.0.7 2012-08-25 【機能拡張】期間による目盛間隔の自動調整(副目盛の活用)
Y軸目盛線とグラフ秒が重なる場合に副目盛間隔一つ分進める
【初期設定】ほぼ全ての埋込み初期設定値を関数の引数に変更しカプセル化
グラフ出力期間をstartとendのコマンドオプションで指定可能に
【処理改善】DB Connectionを大元で生成、関数の引数渡しとし生成負荷を低減
0.0.8 2012-09-20 【機能改善】生成グラフX軸の時系列目盛を期間により適切に変更する様に
目盛ラベルの各種設定値の変更を関数化
【障害対策】指定センサーの一部または全てにデータが無い場合の対処加筆
【コメント】mireのpythonコード恒例通り、ほぼ全行コメントで埋め尽くした。
【初期設定】単純な数値と文字列変数についてコマンドオプションで指定可能に
0.0.9 2012-09-21 【Clean Up】Blog掲載制限回避の為、コメントや不要な記述を整理
0.0.9a 2012-09-22 【機能拡張】画像背景色と透明度、凡例背景の透明度設定を追加"""

def sensors():
u"""
ipmitool sensor で得られるセンサー値を
辞書として数値リストで返す関数
"""
from os import popen
# ipmitool sensor > /tmp/result_of_ipmitool_sensor.txt を実行
result_txt = "/tmp/result_of_ipmitool_sensor.txt"
cmd_ipmi_Sensor = "ipmitool sensor > %s" % (result_txt)
pp = popen(cmd_ipmi_Sensor, 'r')
pp.close()

# /tmp/result_of_ipmitool_sensor.txt を
#linesに読込み
fpi = open(result_txt, "r")
lines = fpi.readlines()
fpi.close()

# 各行をリストにして、itemsリストに挿入する
items=[]
for l in lines:
#print l,
itms = l.split('|')
#print itms
item = []
for itm in itms:
i = itm.strip()
try:
i = float(i)
except:
#print 'Error:', item
pass
if i == 'degrees C':
i = u'°C'
elif i == 'unspecified':
i = '%'
elif i == 'discrete':
i = u' '
elif i == 'na':
i = 'N/A'
elif i == 'nc':
i = '(NC)'
elif i == '0x0':
i = 0
item.append(i)
items.append(item)
#print items
#itemname, value, unit, na, na, na, threshold, critical
#makes item files or stdout for other management system
Sensor = {}
for itm in items:
Sensor[itm[0]] = itm[1:]
return Sensor

def prn_sensors():
u"""
ipmitool sensorのデータをコンソール出力
"""
# 関数Sensors()を実行し、項目: 値 単位を表示 ℃
datas = sensors()
#print datas
keys = datas.keys()
keys.sort()
item_name = ('測定項目', '測定値', '単位', '判定', '閾値', '危急')
print '%-24s: %-10s %-4s %-8s %-9s %-9s' % item_name
for k in keys:
s = '%-20s:' % ('\''+k+'\'')
try:
s = s + ' %7.3f' % (datas[k][0])
except:
s = s + ' %-7s' % (datas[k][0])
try:
s = s + ' %-4s %-6s %7.3f %7.3f' % (datas[k][1], datas[k][2]
, datas[k][7], datas[k][8])
except:
s = s + ' %-4s %-6s %7s %7s' % (datas[k][1], datas[k][2]
, datas[k][7], datas[k][8])
print s

def ins_db(datas, now, dsn='127.0.0.1:default.fdb'
, user='SYSDBA', password='pass', charset='UTF-8'):
u"""
ipmtool sensorの吐くデータと測定日時をDB書込み
"""
import fdb # Firebird接続にfdbを活用
conn = fdb.connect(dsn=dsn, user=user, password=password, charset=charset)
cur = conn.cursor()
#print 'datas=', datas
skeys = datas.keys()
skeys.sort()
for key in skeys:
sql_select_id = 'SELECT SENSOR_ID FROM SENSOR WHERE SENSOR_NAME=\'%s\';'
#print key
cur.execute(sql_select_id % (key))
sensor_id = cur.fetchone()
if sensor_id:
sql_ins='INSERT INTO SENSOR_LOG (YMD_HMS, SENSOR_ID, SVALUE) VALUES (\'%s\', %d, %f);'
try:
cur.execute(sql_ins % (now, sensor_id[0], datas[key][0]))
conn.commit()
except:
print 'Error: %s ,%s, %s, %s' % (sql_ins, now, sensor_id[0], datas[key][0])
conn.close()

def names_dic(dsn='127.0.0.1:default.fdb', user='SYSDBA', password='pass'
, charset='UTF-8', conn=None, cur=None):
u"""
センサーIDに対する表示名の辞書を返す関数
"""
names={}
import fdb # Firebird接続にfdbを活用
if cur==None:
if conn==None:
conn = fdb.connect(dsn=dsn, user=user, password=password, charset=charset)
create_conn_in_func = True
else:
create_conn_in_func = False
cur = conn.cursor()
else:
create_conn_in_func = False
sql_qry = 'SELECT a.SENSOR_ID, a.SENSOR_NAME, a.DISP_NAME FROM SENSOR a'
cur.execute(sql_qry)
datas = cur.fetchall()
if create_conn_in_func==True:
conn.close()
for data in datas:
names[data[0]]=data[-1]
return names

def query_datas(sensor_ids=[], dsn='127.0.0.1:default.fdb', user='SYSDBA', password='pass'
, charset='UTF8', start='', end='', conn=None, cur=None, debug=0):
u"""
DB上のDataを読込む関数
"""
import fdb # Firebird接続にfdbを活用
from datetime import datetime
if debug>0:
st = datetime.now()
if cur==None:
if conn==None:
conn = fdb.connect(dsn=dsn, user=user, password=password, charset=charset)
create_conn_in_func = True
else:
create_conn_in_func = False
cur = conn.cursor()
else:
create_conn_in_func = False

if len(sensor_ids)==1: # 単一IDのwhere条件なら
sql_qry = """SELECT b.YMD_HMS, b.SVALUE FROM SENSOR a
LEFT OUTER JOIN SENSOR_LOG b ON a.SENSOR_ID=b.SENSOR_ID
WHERE a.SENSOR_ID=%d""" % (sensor_ids[0]) + """%s%s
ORDER BY b.YMD_HMS;"""
elif len(sensor_ids)>1: # 複数IDのwhere条件有りなら、IDを附加したqueryで全て一括取得
wheres=[]
for id in sensor_ids:
wheres.append('a.SENSOR_ID=%d' % (id))
whereis=' or '.join(wheres)
sql_qry = """SELECT b.YMD_HMS, b.SVALUE, b.SENSOR_ID FROM SENSOR a
LEFT OUTER JOIN SENSOR_LOG b ON a.SENSOR_ID=b.SENSOR_ID
WHERE %s""" % (whereis) + """%s%s
ORDER BY b.YMD_HMS;"""
else: # IDのwhere条件無しなら
sql_qry = """
SELECT b.YMD_HMS, b.SVALUE FROM SENSOR a
LEFT OUTER JOIN SENSOR_LOG b ON a.SENSOR_ID=b.SENSOR_ID
WHERE %s%s
ORDER BY b.YMD_HMS;"""
if not len(start.strip())==0:
ws = ' and b.YMD_HMS>=\'%s\'' % (start)
else:
ws = ''
if not len(end.strip())==0:
we = ' and b.YMD_HMS<=\'%s\'' % (end)
else:
we =''
#print sql_qry % (sensor_ids, ws, we)
cur.execute(sql_qry % (ws, we))
datas = cur.fetchall()
if create_conn_in_func==True:
conn.close()
if debug>0:
et = datetime.now()
print 'query_datas():', et - st
return datas

def set_graph_params(subplot, major_format=None, minor_format=None
, major_locator='day', major_by=None, major_interval=1, major_bymonthday=1
, minor_locator='hour', minor_by=None, minor_interval=1, minor_bymonthday=1
, yearmonth=1, yearday=1, tz=None

, major_label=None
, major_fontcolor=None, major_fontsize=None, major_fontfamily=None
, major_fontstyle=None, major_fontstretch=None, major_fontweight=None
, major_rotation=None, major_dy=0, major_horizontalalignment=None
, major_verticalalignment=None

, minor_label=None
, minor_fontcolor=None, minor_fontsize=None, minor_fontfamily=None
, minor_fontstyle=None, minor_fontstretch=None, minor_fontweight=None
, minor_rotation=None, minor_dy=0, minor_horizontalalignment=None
, minor_verticalalignment=None

, lines_width=None, markers_size=None
):
u""""
目盛設定を行なう関数
主副目盛に指定の時系列LocatorとDateFormatterの各引数を指定し設定
* 目盛ラベル文字列が不要な場合はNoneのままで
*
"""
import matplotlib.dates as mdates #日時様式[for DateFormatter,HourLocator, etc...]

if not major_format==None:
subplot.xaxis.set_major_formatter(mdates.DateFormatter(major_format)) #主目盛ラベル様式
if not minor_format==None:
subplot.xaxis.set_minor_formatter(mdates.DateFormatter(minor_format)) #副目盛ラベル様式

if major_by==None: #主目盛のlistによる間隔指定がないなら、intervalで間隔指定を優先
if major_locator=='second':
subplot.xaxis.set_major_locator(mdates.SecondLocator(interval=major_interval, tz=tz))
elif major_locator=='minute':
subplot.xaxis.set_major_locator(mdates.MinuteLocator(interval=major_interval, tz=tz))
elif major_locator=='hour':
subplot.xaxis.set_major_locator(mdates.HourLocator(interval=major_interval, tz=tz))
elif major_locator=='day':
subplot.xaxis.set_major_locator(mdates.DayLocator(interval=major_interval, tz=tz))
elif major_locator=='month':
subplot.xaxis.set_major_locator(mdates.MonthLocator(bymonthday=major_bymonthday
, interval=major_interval, tz=tz))
elif major_locator=='year':
subplot.xaxis.set_major_locator(mdates.YearLocator(base=major_interval
, month=yearmonth, day=yearday, tz=tz))
else: #そうでないなら、major_byのlistによる間隔指定を優先
if major_locator=='second':
subplot.xaxis.set_major_locator(mdates.SecondLocator(bysecond=major_by
, interval=1, tz=tz))
elif major_locator=='minute':
subplot.xaxis.set_major_locator(mdates.MinuteLocator(byminute=major_by
, interval=1, tz=tz))
elif major_locator=='hour':
subplot.xaxis.set_major_locator(mdates.HourLocator(byhour=major_by
, interval=1, tz=tz))
elif major_locator=='day':
subplot.xaxis.set_major_locator(mdates.DayLocator(bymonthday=major_by
, interval=1, tz=tz))
elif major_locator=='month':
subplot.xaxis.set_major_locator(mdates.MonthLocator(bymonth=major_by
, bymonthday=major_bymonthday
, interval=1, tz=tz))
elif major_locator=='year': #yearではmajor_byは無いが、馬鹿避けで重複記載
subplot.xaxis.set_major_locator(mdates.YearLocator(base=major_interval
, month=yearmonth, day=yearday, tz=tz))

if minor_by==None: #副目盛のlistによる間隔指定がないなら、intervalで間隔指定を優先
if minor_locator=='second':
subplot.xaxis.set_minor_locator(mdates.SecondLocator(interval=minor_interval, tz=tz))
elif minor_locator=='minute':
subplot.xaxis.set_minor_locator(mdates.MinuteLocator(interval=minor_interval, tz=tz))
elif minor_locator=='hour':
subplot.xaxis.set_minor_locator(mdates.HourLocator(interval=minor_interval, tz=tz))
elif minor_locator=='day':
subplot.xaxis.set_minor_locator(mdates.DayLocator(interval=minor_interval, tz=tz))
elif minor_locator=='month':
subplot.xaxis.set_minor_locator(mdates.MonthLocator(bymonthday=minor_bymonthday
, interval=minor_interval, tz=tz))
elif minor_locator=='year':
subplot.xaxis.set_minor_locator(mdates.YearLocator(base=minor_interval
, month=yearmonth, day=yearday, tz=tz))
else: #そうでないなら、minor_byのlistによる間隔指定を優先
if minor_locator=='second':
subplot.xaxis.set_minor_locator(mdates.SecondLocator(bysecond=minor_by
, interval=1, tz=tz))
elif minor_locator=='minute':
subplot.xaxis.set_minor_locator(mdates.MinuteLocator(byminute=minor_by
, interval=1, tz=tz))
elif minor_locator=='hour':
subplot.xaxis.set_minor_locator(mdates.HourLocator(byhour=minor_by
, interval=1, tz=tz))
elif minor_locator=='day':
subplot.xaxis.set_minor_locator(mdates.DayLocator(bymonthday=minor_by
, interval=1, tz=tz))
elif minor_locator=='month':
subplot.xaxis.set_minor_locator(mdates.MonthLocator(bymonth=minor_by
, bymonthday=minor_bymonthday, interval=1, tz=tz))
elif minor_locator=='year': #yearではminor_byは無いが、馬鹿避けで重複記載
subplot.xaxis.set_minor_locator(mdates.YearLocator(base=minor_interval
, month=yearmonth, day=yearday, tz=tz))
set_ticks_label(ticks=subplot.xaxis.get_major_ticks(), label=major_label
, dy=major_dy, rotation=major_rotation
, fontcolor=major_fontcolor, fontsize=major_fontsize
, fontfamily=major_fontfamily, fontstyle=major_fontstyle
, fontweight=major_fontweight, fontstretch=major_fontstretch
, horizontalalignment=major_horizontalalignment
, verticalalignment=major_verticalalignment)
set_ticks_label(ticks=subplot.xaxis.get_minor_ticks(), label=minor_label
, dy=minor_dy, rotation=minor_rotation
, fontcolor=minor_fontcolor, fontsize=minor_fontsize
, fontfamily=minor_fontfamily, fontstyle=minor_fontstyle
, fontweight=minor_fontweight, fontstretch=minor_fontstretch
, horizontalalignment=minor_horizontalalignment
, verticalalignment=minor_verticalalignment)
if not lines_width==None:
## 各要素のマーカーSizeと線幅を太くし視認性を高める ##
lines = subplot.get_lines()
if not markers_size==None:
for l in lines:
l.set_markersize(markers_size)
l.set_linewidth(lines_width)
else:
for l in lines:
l.set_linewidth(lines_width)
else:
if not markers_size==None:
lines = subplot.get_lines()
for l in lines:
l.set_markersize(markers_size)

def set_ticks_label(ticks, label=1, dy=0, rotation=None
, fontcolor=None, fontsize=None #, fontproperties=None
, fontfamily=None, fontstyle='normal'
, fontweight='normal', fontstretch='normal'
, horizontalalignment=None, verticalalignment=None):
u"""
目盛ラベルの各種設定値の変更
(ここで必要なもののみコーディング。目盛ラベルに対する全てを網羅してはいない)
【使い方】
ticks = subplot.xaxis.get_major_ticks()
chgtick(ticks=ticks, label=1, color=None, verticalalignment)
"""
from matplotlib.font_manager import FontProperties
ticks_font = FontProperties(family='times new roman', style='normal'
, size=12, weight='normal', stretch='normal')

for tick in ticks:
if label==2: #適用対象がlabel1なら
ticklabel=tick.label2 # tick.label2
else: #それ以外は
ticklabel=tick.label1 # tick.label2
if not fontsize==None:
tick.label.set_fontsize(fontsize) #目盛ラベル文字列の文字Size
if not fontcolor==None:
ticklabel.set_color(fontcolor) #目盛ラベル文字列の文字色
if not fontfamily==None:
tick.label.set_fontproperties(FontProperties(family=fontfamily #目盛ラベル文字列の
, style=fontstyle, weight=fontweight, stretch=fontstretch)) #フォントプロパティ
if not verticalalignment==None: #目盛ラベル文字列の
ticklabel.set_verticalalignment(verticalalignment) #垂直方向の位置合わせ
if not horizontalalignment==None: #xdate_horizontal_alignment()
ticklabel.set_horizontalalignment(horizontalalignment) #が優先され無効
if not rotation==None:
ticklabel.set_rotation(rotation) #目盛ラベル文字列の傾け角
if not dy==0: #Y座標を増減し主目盛ラベルの
ticklabel.set_position([0, dy]) #配置を縦方向にずらす
続きを読む
posted by Mire at 00:20 | Comment(0) | TrackBack(0) | 自宅サーバ構築管理 | このブログの読者になる | 更新情報をチェックする

2012年09月16日

【自宅サーバ構築】10. HP ProLiant ML110 G7温度&FAN回転率解析結果

 自宅サーバ運用では発熱とそれに伴うFAN回転上昇による騒音が生活空間の質を低下させることにつながることが最大の課題となる。またFAN回転上昇は当然その分電力消費量の上昇にもつながるので昨今の反原発キャンペーンによる電力需給逼迫下では省エネにも努めたいところである。

 当方も、この暑い夏の間、色々と対策をしつつ、例のipmiSensor.pyで連続計測を行なって来たのだが、昨今では、秋台風の到来や秋雨前線による雨が増え酷暑の残暑は終焉した模様で、FAN回転数が最高の78.4%になることがなくなったので、これ迄の解析結果を一例として、ここに掲載する。
 数値自体は「HP ProLiant ML110 G7 OSレスモデル 6473360-AHZN」内のセンサーをcrondで採取したものだが、示す数値は設置環境を主要因として決まる。またサーバ機CPUの種類や省エネ設定やCPU稼働率、そしてメモリーやHDD、拡張ボード等の装着状況次第でも様相が大きく変わるものだ。当方では「HP ProLiant ML110 G7 OSレスモデル 6473360-AHZN」(Celeron G530 2.4GHz)に Memory 4G bite, HDD x3を実装し、BIOSでCPU周波数制御をOSに渡し、CentOS6.3標準のCPUSpeed制御の様なkernel制御?に委ねている為、未公開の低負荷状態では概ね最低ステップの1.6GHzの省エネ優先運転となっている。サーバ機を設置しているのは木造2階建ての1階南西角の居室で南東の角の1階にあるが、夏場は家の屋根と南側の隣家の影になることから南側の窓から日が射すことはほとんどないが南側の窓は下方にガラリのついた雨戸を締め輻射熱の侵入を防いでいる。ただ西側は小さな庭を挟み4m幅の公道となっていたりで視界が開けているので西陽だけは容赦なく射してくる。これにはレースと厚手のカーテンで防いでいる。この南側と西側の窓は共に網戸ごしに開放、北角の部屋の入口も開けっ放すことで可能な限り自然換気が出来る様にしている。
 尚、途中からは西側窓の外側にすだれを掛けて日差しを軽減したり、サーバー機の表側に1Lのペットボトルに水を入れたものを3本置き、その水の蓄熱放熱効果で急激な気温変動を低減させる試みをしている。ペットボトル自体が厳密どの程度効果があるのかは判らないが、PCが示す気象の気温に比べ±2度程度低減されている。単体での測定のみで一切比較対象がないのでその検証は他の方の記録に頼るしかない。そこん所、どなたか宜しく ^_^;/


 只、ipmiSensor.pyによる自動測定開始自体は既に回転数が上がりFAN騒音が気になり始めてからの泥縄対応だった為、今夏の全てを網羅出来ていなかった。しかし幸いハンド処理で「date; sudo ipmitool sdr」や「date; sudo ipmitool sensor」を実行したコンソール出力のLogを取得していたので、これらをDBにハンド入力することで早朝気温21度であった7月上旬のころ迄遡り、データ補完させて頂いた。ハンド入力の部分は不定期な間隔での測定なので、マーカーが離れている箇所はサンプリング不足で時々の変動推移とピーク値を表していない。当方の設置場所では早朝の日の出の時刻に最低気温となり日没の時刻頃に最高気温となり各センサー値が変動することを考慮してご覧頂きたい。続きを読む
posted by Mire at 15:15 | Comment(0) | TrackBack(0) | 自宅サーバ構築管理 | このブログの読者になる | 更新情報をチェックする

2012年08月17日

【Linux】「lshw」でバード情報取得

 CPUを含むハード情報は「dmidecode」で出力し確認出来る。しかしCPUの情報を見ると以下の様に見易く出力される。しかし、「Upgrade: Socket LGA1366」と意味不明の記述に加え、「Max Speed: 4800 MHz」と規格の倍表記だったり、「Current Speed: 2400 MHz」と常に最大周波数が出力される為、いささか眉唾もの感が否めない。それでWindowsアプリのCPU-X的なLinuxアプリを探して試た。それが首記の「lshw」である。「lshw」では、少なくともSpeed数字上の齟齬は無い様だ。



[mire@mire_server ~]$ sudo dmidecode --type=4
[sudo] password for mire:
# dmidecode 2.11
SMBIOS 2.6 present.

Handle 0x0400, DMI type 4, 42 bytes
Processor Information
Socket Designation: Proc 1
Type: Central Processor
Family: Xeon
Manufacturer: Intel
ID: A7 06 02 00 FF FB EB BF
Signature: Type 0, Family 6, Model 42, Stepping 7
Flags:
FPU (Floating-point unit on-chip)
VME (Virtual mode extension)
DE (Debugging extension)
PSE (Page size extension)
TSC (Time stamp counter)
MSR (Model specific registers)
PAE (Physical address extension)
MCE (Machine check exception)
CX8 (CMPXCHG8 instruction supported)
APIC (On-chip APIC hardware supported)
SEP (Fast system call)
MTRR (Memory type range registers)
PGE (Page global enable)
MCA (Machine check architecture)
CMOV (Conditional move instruction supported)
PAT (Page attribute table)
PSE-36 (36-bit page size extension)
CLFSH (CLFLUSH instruction supported)
DS (Debug store)
ACPI (ACPI supported)
MMX (MMX technology supported)
FXSR (FXSAVE and FXSTOR instructions supported)
SSE (Streaming SIMD extensions)
SSE2 (Streaming SIMD extensions 2)
SS (Self-snoop)
HTT (Multi-threading)
TM (Thermal monitor supported)
PBE (Pending break enabled)
Version: Intel(R) Celeron(R) CPU G530 @ 2.40GHz
Voltage: 1.4 V
External Clock: 100 MHz
Max Speed: 4800 MHz
Current Speed: 2400 MHz
Status: Populated, Enabled
Upgrade: Socket LGA1366
L1 Cache Handle: 0x0710
L2 Cache Handle: 0x0720
L3 Cache Handle: 0x0730
Serial Number: Not Specified
Asset Tag: Not Specified
Part Number: Not Specified
Core Count: 2
Core Enabled: 2
Thread Count: 2
Characteristics:
64-bit capable

[mire@mire_server ~]$

続きを読む
posted by Mire at 21:39 | Comment(0) | TrackBack(0) | Linux | このブログの読者になる | 更新情報をチェックする

2012年08月14日

【嵌りました】CRONで動かない! cron jobに環境変数LANGは引継がれず

 cron設定では、時々、上手く自動実行出来ずにあたふたすることがあるが、それは概ねスクリプトの実行権限設定なり、/etc/cron.d/内のファイル記述ミスの問題で、crondの実行タイミングを避けて「sudo service crond.restart」辺りでcrondのサービスを再起動させ認識させてば次回の実行タイミングから実行される。

 しかし、今回、前稿の「HP ProLiant ML110 G7 OSレスモデル 6473360-AHZN」のセンサー値のDB書込みPythonプログラムに、im_sensors経由のCPU Coreの温度センサー値を附加したところ、手動ではDB書込み迄実行出来るものの、crondでは、どうもim_sensorsの処理のところで例外発生で異常終了してしまっている様だった。
 その間のDB書込みは、これ迄のipmiの分迄は追加スクリプトの前に記述し個別にcommit迄される仕様としたので事なきを得たが、手動実行時と異なり、明示的な例外処理記述をしていないもののcron job実行のメッセージは「/var/log/messages」に次の様に、「何かあったよ!」程度の目立たないログを残す程度であり、今回は真の原因を見逃してしまいcrondの使い方の誤り思い込み右往左往してしまった次第だ。
「 abrt: detected unhandled Python exception in '/usr/local/bin/ipmi_and_sensors.py'」

 原因は首記の通りcron job実行では「環境変数LANGが引継がれない仕様」だからで、その為、im_sensorsのデータ取得で活用した「sensors」コマンドの実行時にlocaleに「LANG=ja_JP.UTF-8」が適用されない為、出力文字に変化があり、pythonの文字列処理で不測の事態を生じたからであった。それでは、先ずは、このことを
確認する為の簡単なcron jobを示し「cron jobにrootの環境変数LANGは引継がれない仕様」を明らかにしよう。
続きを読む
posted by Mire at 14:46 | Comment(0) | TrackBack(0) | Linux | このブログの読者になる | 更新情報をチェックする
月額見放題1,000円開始キャンペーンバナー(画像ありver)
紺碧の艦隊 ルパン三世 GREAT CHASE クリックプロモーション
<< 2013年01月 >>
    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    
カテゴリ
タグクラウド
ファン
利用中のオープンソース
最近のコメント
最近の記事
過去ログ
QRコード
レガシーなアプリはいかが?
Dell 法人のお客様ページ
  • 【法人様向け】デル、お得なキャンペーン情報
  • 法人のお客様向け ストレージソリューション
  • 法人のお客様向け ネットワークソリューション
  • 【SOHO法人様向け】デル・オンライン広告限定ページ
  • デル-個人のお客様ページ
  • 【個人のお客様向け】デル・オンライン広告限定ページ
  • オンライン広告限定キャンペーンページ
  • ソフトウェア&周辺機器 パソコン工房
    ツートップインターネットショップ(twotop.co.jp) マウスコンピューター/G-Tune
  • ×

    この広告は1年以上新しい記事の投稿がないブログに表示されております。