Personal tools
You are here: Home 清水川記 Categories Programming
Document Actions

Programming

Up one level

Document Actions

アクセス数計測

先週辺りから、Worldから自宅サーバーへのアクセスが出来ない現象が多発しています。サーバーのOSを入れ替えてからOSそのものは落ちていないようなのですが、ナゼか外部からアクセスできなくなるようです。試しに定期的に外部にメールを発信するようにしたところ、そのタイミング毎にアクセスが可能になるようで、OSというよりはルータとかを疑った方が良いような気がしてきました。

ところで、今日は何時頃にアクセスできなくなっていたのか、というのを知りたくなったので、apacheのアクセスログを集計してみることにしました。最近pythonで簡単なプログラムを書くのが趣味になりつつあるので、今日もまたpythonで書いてみます。

apacheのログから時間単位のアクセス数を計算:

#!/usr/local/bin/python

import fileinput
import re

date = re.compile("(\d+)/\w+/\d+:(\d+):(\d+):(\d+)")
hour = ""
times = 0

for line in fileinput.input("/var/log/httpd/freia-access.log"):
  time = date.search(line)
  if time:
    groups = time.groups()
    group = groups[0]+" "+groups[1]
    if hour != group:
      print "%s: %s" % (hour, "*"*(times/10))
      hour = group
      times = 0
    times += 1

print "%s: %s" % (hour, "*" *(times / 10))

結果はこんな感じです:

12 00: ************
12 01: *******************************
12 02: *********
12 03: *
12 04: *****
12 05: ***********
12 06: *********
12 07: ******
12 08: ***************
12 10: ********
12 11: ***************
12 12:
12 13: *************
12 14: ************************************************
12 15: *****************************************
12 16: ****************************
12 17: ******************************
12 18: ********************
12 19: **********************
12 20: ***********************
12 21: **************************
12 22: ****************************
12 23: ******

‥‥ここまでやってから気づいたのですが、これでは単なるアクセス数集計で、どの辺りでアクセスが途切れているかを知ることは出来ません。だめじゃん。

とりあえず1分単位で集計して途切れタイミングを知ることだけは出来そうですが、会社のサーバーあたりにcron仕掛けて調べる方が現実的ですね。

アクセス隙間検出

アクセス隙間検出。悔しかったのでリベンジです。

datetimeモジュールとtimeモジュールの間でうまく連携する方法が分からなかったので、かなり泥臭い感じになってしまいました。あとprevtimeとbasetimeの初期化が‥‥。

apacheのログから10分以上アクセスの無い時間帯を検出:

#!/usr/local/bin/python

import fileinput
import re
import time
import datetime

date = re.compile("(\d+/\w+/\d+:\d+:\d+:\d+)")
prevtime = None
basetime = None

for line in fileinput.input("/var/log/httpd/freia-access.log"):
  logtime = date.search(line)
  if logtime:
    ttime = time.mktime(time.strptime(logtime.groups()[0],
    "%d/%b/%Y:%H:%M:%S"))
    dtime = datetime.datetime.fromtimestamp(ttime)
    if not prevtime:
      prevtime = dtime
      basetime = dtime

    if dtime - prevtime < datetime.timedelta(0,600):
      if basetime != prevtime:
        print "%s while %s" % (basetime, dtime - basetime)
      basetime = dtime

    prevtime = dtime

結果はこんな感じ:

2004-08-12 00:31:07 while 0:32:59
2004-08-12 01:18:19 while 0:12:00
2004-08-12 03:17:27 while 0:42:16
2004-08-12 04:24:20 while 0:25:58
2004-08-12 04:50:22 while 0:19:45
2004-08-12 05:12:41 while 0:19:16
2004-08-12 05:46:56 while 0:13:45
2004-08-12 06:27:23 while 0:11:36
2004-08-12 06:46:56 while 0:25:55
2004-08-12 07:22:50 while 0:14:44
2004-08-12 07:48:35 while 0:14:38
2004-08-12 08:56:30 while 1:07:35
2004-08-12 10:28:47 while 0:23:49
2004-08-12 12:12:04 while 0:48:02
2004-08-12 13:15:28 while 0:44:42

やった!出来た!(笑)

結果を見ると、朝9時と正午前後あたりに外部からアクセスできていない時間帯があります。未だ原因は分かっていませんが、とりあえず定期的に外部に通信を行うようにして回避してみたいと思います。

pyuiをいじってみる

久しぶりのpythonです。今回は pyui をいじってみます。 pyui はGUI系のライブ ラリなので、Xを設定していないFreeBSDではなくWindows上で動かすために、 pythonのインストールから行いました。

  1. Python日本語環境用インストーラ (python23jp-20030906.exe)
  2. PyGame (pygame-1.6.win32-py2.3.exe)
  3. PyOpenGL (PyOpenGL-2.0.1.08.py2.3-numpy23.exe)
  4. PIL (PIL-1.1.4.win32-py2.3.exe)
  5. GLUT (glut-3.7.6-bin.zip)
  6. pyui (pyui095.zip)

GLUTpyui 以外はインストーラで簡単にインストールすることが出来ました。 GLUT はOpenGLを手抜き利用するためのものらしいですがよく知りません。入手し たパッケージに入っているglut32.dllを\Windows\system32に入れました。

pyui は最新版の1.00があるのですが、間違って0.95を使用しました。0.95のパッ ケージにはWindows専用インストーラは含まれていませんでしたので、展開してコマ ンドラインから以下のコマンドを入力してインストールしました:

c:\pyui95> python setup.py install

準備が整ったので、早速実験です。まずは pyui のサイトにあるサンプルを入力し て、以下の最小のサンプルに行き着きました:

import pyui
pyui.init(400,300)
pyui.run()

真っ黒なWindowが表示されて、あとはコンソールにFPSが流れていきます。さすがに 意味のあるサンプルにしたいので、もう一行追加:

import pyui
pyui.init(400,300)
pyui.widgets.Frame(10,10,100,100,"test")
pyui.run()

無事Windowが表示されたところで、今日はここまで:

pyui.quit()

おまけ: pyui.widgets.Frame() を3つ出してみる

System Message: WARNING/2 (<string>, line 38)

Title underline too short.

おまけ: pyui.widgets.Frame() を3つ出してみる
--------------------------------------

pyuitest1

pyuiの練習

今日はpyuiのmenuをいじってみました:

import pyui
pyui.init(800,600)
def onCreate(item):
 pyui.widgets.Frame(50,50,100,100,item.text)
menu=pyui.widgets.Menu("create")
menu.addItem("Green", onCreate)
menu.addItem("White", onCreate)
menubar = pyui.widgets.MenuBar()
menubar.addMenu(menu)
pyui.run()

しかし、これではつまらないので、Menuの選択毎に違う挙動をさせてみたいと思います。本来であれば挙動を定義した関数(上記の例ではonCreate)を複数用意してそれぞれのMenuItemに登録するところですが、ここではlambdaを使って1行で書いてみたいと思います:

import pyui
pyui.init(800,600)
menu=pyui.widgets.Menu("create")
menu.addItem("Window" ,lambda item: pyui.widgets.Frame(50,50,100,100,item.text))
menu.addItem("Console",lambda item: pyui.dialogs.Console(100,100,200,100))
pyui.widgets.MenuBar().addMenu(menu)
pyui.run()

なかなかすっきりしました。

実際の所、lambdaの乱用はしない方が賢明なのですが、とりあえずlambdaの練習ということで、もう一歩踏み込んでlambdaを使ってみました:

import pyui
pyui.init(800,600)
pyui.widgets.MenuBar().addMenu((lambda menu=pyui.widgets.Menu("create"): menu.addItem("Window",lambda item: pyui.widgets.Frame(50,50,100,100,item.text)) and menu.addItem("Console",lambda item: pyui.dialogs.Console(100,100,200,100)) and menu)())
pyui.run()

もう読めません(笑)

途中からpyuiは関係なくなってしまいましたが、こんな事も出来る、というのを体験してみたかったと言うことで。 おかげで、既存のpythonのコードを読んでいて時々出てくる and と or を使用したif文の短絡表記方法が理解できました。

やはり習うより慣れろ、という事で、実際にコードを書かないと文法とか表現って身に付かないですね。

ドキュメント自動生成計画

仕事のプロジェクトで、慢性的に人手が足りていません。そこで、ドキュメントは出来るだけ自動生成にしようと画策しています。

今のところ、 doxygenCUnit を使用して以下のドキュメントが自動生成されています。

  • APIリファレンス
  • 単体テスト項目書
  • 単体テスト成績書

会社のモノを勝手に公開するわけにはいかないので、残念ながら成果物を掲載することは出来ないのですが、生成手順についてメモしておきます。

APIリファレンス

doxygen_ → html → HTML Help

htmlからWindowsのHTMLHelp形式にするためには、MicrosoftのサイトからHTML Help Workshopをダウンロードしてインストールしておく必要があります。あとはdoxyfileにGENERATE_HTMLHELP = YES と記述して、関連する項目(コンパイラのパス等)を設定するだけで、doxygenが自動的に生成してくれます。

ただし、あまり見やすいヘルプは作ってくれません。自分は、@mainpage と @defgroup を使って、提供機能からAPIを引けるように工夫してみました。

単体テスト項目書

doxygen_ → XML → 自作XSLTと結合して HTML

GENERATE_XML = YES とすることで、 doxygen はXMLを出力してくれます。そこで、XMLに自作のXSLTを結合させて、自動生成のHTML(HTMLHelp)よりも見やすく作ってみました。XMLとXSLTの結合には Apache XML project の xt を使用しました。

xt導入 には若干手間取りましたが、googleで見つけたサイトで手順が書かれていたので、すんなりと導入することが出来ました。‥‥が、IE6.0の出力結果と微妙に違うようです。

実はHTMLに変換した理由は別にあって、WordでHTMLを読み込ませて、Wordファイルとして提出するためだったりします。別にWordじゃなくても‥‥とか思うんですけどねぇ。

単体テスト成績書

CUnit_ → XML → 自作XSLTと結合して HTML

CUnit もXMLを出力することが出来るので、これもXSLTを用意しました。項目書と成績書の両方ともXMLなのだから、もう一工夫すれば項目書にテスト結果も載せることが出来ると思います。今回は時間が無いので、これは次回の課題としておきます(^^;

今後の自動生成

次は、後日メンテ用の内部設計書ですかね。あと、コマンド一発で

  1. VSSからソース取得
  2. VC++でコンパイル
  3. テスト実行
  4. ドキュメント生成(doxygen,xt)
  5. ドキュメントアップロード

とかやってみたいですね。

Category(s)
Programming

Re: ドキュメント自動生成計画

Posted by うっちー at Jun 08, 2005 03:34 PM

突然質問して申し訳ありません。
うっちーと申します。

CUnitを使用しようとして、セットアップしていますが、
うまくいきません。

Visual Studio 6.0で、CUnit.dswを開いて、
ビルドしようとしていますが、
CUnitはライブラリまで作成できますが、
BasicTestでリンク中外部シンボルは未解決とのエラーになってしまいます。

セットアップの方法が分かるでしたら、
教えていただけないでしょうか?
宜しくお願いいたします。

Re: ドキュメント自動生成計画

Posted by 清水川 at Jun 09, 2005 12:15 AM

> CUnitはライブラリまで作成できますが、
> BasicTestでリンク中外部シンボルは未解決とのエラーになってしまいます。

こんにちは^^

多分、ライブラリと利用側とのコンパイルオプションが異なっているために外部リンケージが見つからないのだと思います。
CUnit のコード生成のオプションはシングルスレッド(/ML)なので、利用側のオプションが一致しているか確認してみてください。異なっていた場合、利用側を合わせるのか、ライブラリ側を変えるのかは必要に応じて決めればいいと思います。

[プログラミング]

Posted by きまぐれのらねこにっき at Nov 28, 2005 12:47 AM

Pythonを利用するDLLのデバッグ

デバッグ版Python32_d.libは標準のパッケージ 1 には同梱されていない。そしてpython.hをincludeすると内部的に以下のようにかかれているので、Debugだとpython23_d.libを自動的にリンクしようとして失敗してしまう。:

#ifdef _DEBUG
    #pragma comment(lib,"python23_d.lib")
#else
    #pragma comment(lib,"python23.lib")
#endif /* _DEBUG */

なので、Pythonを使うC++アプリをVS.NETで作ってもReleaseでしかコンパイルできないのでデバッグが大変。というかDebug版無しに開発するのはIDEに慣れてしまった身としては苦痛。いや、苦痛とか言ってないでUnitTestすればいいんだけど。

どっかにコンパイル済みのpython23_d.libがあるだろ!と思って調べてみたら、 もっと簡単な方法 が:

So if you want you should be able to change your source to something
like this:

#undef _DEBUG
#include <python.h>
#define _DEBUG

あー、なるほどー。

[1]Python 2.3.4 日本語環境用インストーラ(Win32)を使ってます。 http://www.python.jp/Zope/download/pythonjpdist

COREblogのエントリを表示するportlet_recent_blogentries

portlet_recent_images の次に COREblog の最近追加されたエントリ表示をPloneのスロット行う、portlet_recent_blogentriesを作ってみた。 http://www.freia.jp/taka のページで左の柱に表示されていると思う。

作り方は Wiki に記載。ファイルもおいた方が良いかな‥‥?

pythonでHTML解析

会社の同僚が

「Webサイトに定期的にアクセスして内容を解析して○○××を自動的に実行するプログラムを作りたい。 Perlで作ろうと思うんだけど……」

という話をしていたので、Pythonを勧めてみた。ついでにサンプルコードを作ってみた。

myparser.py:

from HTMLParser import HTMLParser

class MyHTMLParser(HTMLParser):
    def handle_data(self, data):
        data = data.strip("  \t\r\n")
        if data:
            print 'Data: "%s"' % data

    def handle_starttag(self, tag, attrs):
        pass
        #print 'TagStart: "%s"' % tag

    def handle_endtag(self, tag):
        pass
        #print 'TagEnd: "%s"' % tag

def main(url):
    import urllib
    data = urllib.urlopen( url )
    mp = MyHTMLParser()
    mp.feed( data.read() )


if __name__ == "__main__":
    import sys
    url = "http://python.jp/"
    if len( sys.argv ) > 1:
        url = sys.argv[1]

    main(url)

これを引数無しで実行すると、python.jpのページが取れてきて以下のように表示される:

Data: "Click"
Data: "here"
Data: "to get to the FrontPage."

超適当に作った割にはちゃんと動いたなぁ。

Re: pythonでHTML解析

Posted by uemura at Mar 23, 2005 04:03 PM

すみません、質問なのですが、

HTMLParserというかpythonで日本語を含むHPを解析しようと思うと
(たとえばunicode(data).encode("sjis")みたいな処理)
失敗するのですが、どのような処理をしたらいいのでしょうか?

Re: pythonでHTML解析

Posted by 清水川 at Mar 24, 2005 12:03 AM

すみません、pythonプロじゃないので全然詳しくないのですが、unicode(data) ってエンコード判別してくれるんでしょうか?APIマニュアル見た感じだと判別してくれないような気が‥‥。

とりあえず、HTTPレスポンスでContent-Typeを返してくれるサーバーの場合は以下のようにしてエンコードを取得することは出来ました。

import urllib
data = urllib.urlopen( url )
charset = data.headers.getparam('charset')

そして以下のようにして文字変換します。

data = unicode(data,charset).encode("sjis")

サーバーがContent-Typeをくれない場合はmeta タグのContent-Typeを見るとか、でしょうか‥‥?それもだめなら自動判別‥‥って、どうやるんだろう?

Re: pythonでHTML解析

Posted by uemura at Mar 24, 2005 11:28 AM

ありがとうございます。
自動判別は難しそうですね。

こんな感じで
import urllib
data = urllib.urlopen( url )
charset = data.headers.getparam('charset')
print charset
charset = "sjis" #本来ならここに自動判別のプログラムを入れる。
mp = MyHTMLParser()
mp.feed(unicode(data.read(),charset).encode("sjis") )

ある程度のものは読めるようになりました。

RSS,AtomのParserであるuniversal feed parser モジュールはこの辺もしっかりやってるんだろうなとソースを読んでみようかと思ったら発狂しそうになりました。

もうちょっといろいろ調べてみようかと思います。

Re: pythonでHTML解析

Posted by uemura at Mar 24, 2005 02:24 PM

なんどもすみません

import urllib
import pykf
cod = ("UNKNOWN","ASCLL","SJIS","EUC-JP","JIS","utf-8","UTF-16-LE","UTF-16-BE","ERROR")
data = urllib.urlopen( url )
urlstring = data.read()
mp = MyHTMLParser()
charset = cod[pykf.guess(urlstring)]
data = urllib.urlopen( url )
mp.feed(unicode(urlstring,charset).encode("sjis") )

PyKfモジュールで判定はできましたけど、
windowsでutf-8をSJISに変換するときにエラーが出るときがあります。

難しいですね。

Re: pythonでHTML解析

Posted by 清水川 at Mar 24, 2005 10:42 PM

> PyKfモジュールで判定はできましたけど、

おお!すばらしい!!参考にさせていただきます。
とはいえ、自動判別については、既存のブラウザでも完璧なのは無いですし、うまくいかなくてもしょうがない部分はありますね。

> windowsでutf-8をSJISに変換するときにエラーが出るときがあります。

SJISに無い文字が混ざっているとか?(あてずっぽう)

Re: pythonでHTML解析

Posted by i? at Mar 25, 2005 09:38 AM

ここの 683に、いくつかのencodingで変換試して
UnicodeExceptionの場合ハズレ、という方法が。

Re: pythonでHTML解析

Posted by 清水川 at Mar 25, 2005 11:21 PM

> ここの 683に

それはよい方法だね!
実際の所、pykfが無い環境で近似的にやるにはリーズナブルだなぁ。(pykf, 中で同じ方法でチェックしてたりして‥‥)

Re:pythonでHTML解析

Posted by nagaetty at Feb 25, 2007 11:12 PM

python勉強中のものです。大変参考になるソースをありがとうございます。
pykfのあるページが参照できなくなっているので、
http://www.python.jp/Zope/download/pythonjpdist
のWindowsインストーラを入手して、自分のページを参照してみました。

Re:pythonでHTML解析

Posted by しみずかわ at Feb 25, 2007 11:24 PM

各所で出てますが、webarchiveから入手できますよ~

http://web.archive.org/web/20060206123300/http://gembook.jp/tsum/page.pys?wiki=PyKf

あと、HTML解析については、PythonWorkshopで紹介されたBeautiful Soupが良いかもしれません。良い感じで手を抜けそうです。

http://www.python.jp/Zope/workshop/200612/index_html?pp=1

Ploneの使い方

Posted by PukiWiki/TrackBack 0.1 at Nov 28, 2005 12:48 AM
« March 2010 »
Mo Tu We Th Fr Sa Su
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        
About this blog
Zope, Python, FreeBSD, その他色々について。つまり日記か。
Recent comments
現在翻訳中! しみずかわ Jan 23, 2010
パッチ使わせていただきます 檜山正幸 Dec 21, 2009
いまきづいた jack Dec 19, 2009
Re:讃岐うどん 新宿 楽釜製麺所 jack Dec 19, 2009
Re:讃岐うどん 新宿 楽釜製麺所 とか★ちん Dec 19, 2009
Error
There was an error while rendering the portlet.