過去の桐井戸端BBS (桐ver.8)
12187 フォーム利用状況のログを取る方法 pokopon 2001/07/08-00:54
みなさん、こんにちは。また、お知恵を拝借したいと思います。よろしくお願いします。

やりたい事は、あるフォーム内にあるコマンドボタンを利用した記録(作業内容にあわせた)を取ろうと思っています。
すなわち「利用状況」を把握するLOGです。
利用環境は、桐V8 SP6 NTネットワーク環境で、クライアント数は30〜40くらいでしょうか。

現在は、何かしらのコマンドボタンをクリックした時、イベントを発生させ、
1.「LOG.tbl」の別ファイルを開く(専有で)
2.もし、誰かがこのファイルを利用中(すなわち、LOGを記録中の場合)ならば、そのファイルが空くまでループして待たせる。
3.LOG.tblが空いたら、この表を開き、行挿入して、必要な情報を書き込み、すぐにLOG.TBLを閉じる。
4.その後で、必要な作業用の手続きを実行させる。

という手順でLOG記録を取っています。

最初は調子よく動いていたのですが、クライアント数が多くなってくると、
どうも書き込みのタイミングというか、ファイルを触りにいくタイミング(ファイルの使用状況を調べている間)の関係でしょうか、
あるクライアントが、上記の「ループ」内で止まってしまい(暴走ではありません。
ファイルが空いているのに、ファイルが使用中と判断している? 見かけ上フリーズ状態)、
かつ、そのクライアントが「共有定管理報フォルダ」を利用していた場合、ロックされてしまい、
他の方が桐そのものを起動できなくなってしまいます(良くある現象です)。
どうも、クライアントの機器のスペックにも影響しているようで、「LOG.TBL」を開くのに時間がかかるため、
「表は閉じている」と判断して開こうとするけど、時間がかかってしまい、
その間に別の方が開こうとして開けず・・・・なんて、原因を勝手に予想しています(違うかも?)。
ほんのちょっとしたタイミングのズレかと思いますが、これまた頻繁にこの現象が起こるのです(1日当たり4〜5件)。
その度に、サーバーに駆け込み、そのユーザーの共有資源を切断してあげなければ回復しません。

このファイルロック&書き込みのループは次のように記述しています。

 繰り返し
    条件 ( #ファイル使用( &LogFile , 1) = 1 ) 繰り返し中止
 繰り返し終了
 表 &LogFile ,モード="専有" , 終了状態 = &OK
 ケース開始
  ケース (&RES=1)
     編集表 &LogFile
     行追加 [Date]=#DATE , [Time]=#Time , [User]=#ユーザ名 , [File]=&処理 , [Mode]=&MODE
     終了 表 編集対象表
 ケース終了

ア.であれば、ループを外し「LOG.TBL」そのものを共有モードで開けば?
  ということになりますが、クライアント全員が「共有管理情報フォルダ」を設定している訳ではないのです。
全員には設定できません(全くの素人も居ますし、サーバー環境以外でも桐を使う方は、あえて設定してはいません)。
イ.書き出しコマンドでテキストとして「追加書き込み」すれば?
  どうなんでしょう。まだやってはいませんが、込み合うときにはものすごい利用率ですので、「書き込みエラーが」発生しないのかな?

と、これからどのように管理していくか苦慮しています。
1日当たり1000件くらいのアクセス(作業のためのクリック)があり、込み合う時間帯となれば、
1秒間に5〜6人のアクセスがあります。

すなわち、エラーの少ない「ファイルロック」の仕方というか、効果的なLOGを取る手法とか言うのがありましたら、ご紹介下さい。

桐そのものの機能とはあまり関係しない内容ですけど、よろしくお願いします。

12188 Re:追加説明です pokopon 2001/07/08-01:03
記事番号12187へのコメント
なお、このフォームはメニュー用のフォームで、1つだけ定義しており、皆で共用して利用しています。
ここを起点として、コマンドボタンの機能にあわせてそれぞれの表とフォームを別に開きます。
すなわち各人の利用する本当の表は個別にあり、「共有」では利用していません。
ですので、共用で利用しているのは「LOG記録」のイベントが定義されているメニュー用のフォームだけです。

12189 Re:追加説明です(教えてください。) KH 2001/07/08-06:40
記事番号12188へのコメント
>なお、このフォームはメニュー用のフォームで、1つだけ定義しており、皆で共用して利用して
>います。ここを起点として、コマンドボタンの機能にあわせてそれぞれの表とフォームを別に開
>きます。
>すなわち各人の利用する本当の表は個別にあり、「共有」では利用していません。

pokoponさんおはようございます。
わたし自身興味があったので、ちょっと教えてください。
答えやアドバイスではありません。

>すなわち各人の個別にあり、「共有」では利用していません。

ココの「利用する本当の表は個別にあり」の部分ですが、
これは、最初のフォームのあるサーバー、それとも個々のクライアントにあるという事ですか?

以下は読み流してください。
参考にならないと思いますが、わたし自身は現在、表データはサーバー
(共有でも専有でも選択して各クライアントから開けますが、勿論最初に専有で開けば後の人ははねられます)、
それを利用する一括処理、フォ-ム、レポート、イベントは各クライアントにあります。
そして各クライアントでの作業の履歴を取っています。作業の履歴は表でなく、
100文字程度の文字列(この100文字はメインフォームで作業履歴をリアルタイムで表示しているので表示スペースの問題です。
何文字でも良いのです。)としてvarファイルとして保存しています。
作業履歴の変数の型はどの一括処理に飛んでいっても、
どのイベント内でもフォーム内で履歴が表示できるように当然共通変数です。
各クライアントでどんな作業をしたかが、100文字分だけわかります。
ただ、貴方のような元データの利用状況を全て管理するようなlogではありません。
参考にはならないです。
昨年度、半年がかりで主にこの掲示板を利用させてもらい、V5→V8sp6にコンバートすることが出来ました。
昨年も稼動させていましたがあくまでもテスト利用でした。
今年度4月から本格的に利用しています。
勿論桐の素人がほとんどです(私も知らない事ばかりで万年初心者です)。
唯一桐を使うもう1人は4月に転勤してしまいました。
マニュアルすら作るヒマがありません(コレは嘘で作る気がしなかった)でした。
担当は6人ですが5人は桐全くの素人、6人が同じ部屋にいるので口頭での説明で十分だったのです。
何年か後は全員配置転換になるかもしれませんのでマニュアル作りが必要ですが、
未だに細部の手直しが行われています。
で、直感、共有でやれば簡単かなーなんて考えたのですが、
桐素人へは、共有管理情報の設定等の説明を印刷して配布したらどうかなー(独り言)なんて思ってました。
設定の画面をprint screenで切り取って図入りでマニュアル作ってやると親切ですが、面倒ですね。
失礼しました。
12190 Re:追加説明です(教えてください。) pokopon 2001/07/08-17:34
記事番号12189へのコメント
KHさん こんにちは

>>すなわち各人の個別にあり、「共有」では利用していません。
>
>ココの「利用する本当の表は個別にあり」の部分ですが、これは、最初のフォーム
>のあるサーバー、それとも個々のクライアントにあるという事ですか?
>

全てサーバーにあります。
最初のメニュー用フォーム、及び、クライアントが利用する表を操作するフォームは、全て共用で利用させています。
同じ様式で定義された表ファイルがいくつかあり(50程度)、ファイル名が異なります。
これらの表はクライアントごとにある表ではなく、作業別、目的別に分けてある訳で、もし誰かが利用していれば
「ごめんなさい、現在利用中です」とアナウンスさせています。
すなわち、「専有」で表ファイルは開かせています。
これは全クライアントが「共有モード」で開けない事情があるためで、速度的な面も考慮しています。
まあ、1つの表ファイルを「常に何人も利用する」という事は少ないので、このような管理形式を取っています。
でも、フォームだけはそれぞれの表ファイルごとに作るのが大変なので、全て「共用」させている訳です。
「読み込み専用」ですので、このような使い方をしても、実害はありません。

以上ですが、ご理解いただけましたでしょうか?

12191 Re:参考になるかどうかわかりませんが KH 2001/07/08-21:44
記事番号12190へのコメント
pokoponさん今晩は。回答有難うございました。

タイムラグ確かにあります。ファイルロックは共有状態の場合で、専有で開いた場合はありません。
専有でもクライアントが終了直後、隣のクライアントが少し待たされる事はあります。
ネットワークシステム(ネットウエアーやWIN)が交通整理に時間がかかっているのだと思います。
また、LOGファイルの行数は制限無く限界まで残しておくのですか?かなり大きくなっているのでは?
ログファイルの行数を制限して自動的に古い行を削除するとか、月ごとにLOGファイルを分けるとか・・・

それでも解決しないのなら、
やはり、フォームを開く時に共有更新状態でLOGファイルを開くのが早道では(pokoponさんが意図している方向を無視してゴメンなさい)ないかと思います。
少なくてもフリ−ズ状態にはならないと思います。
処理選択のボタンを押下した時点(正確には該当の処理をするために表が開けた時、
はねられたら書き込まない)で、時間と作業内容を書き込むようにすれば解消すると思いますが。


12192 Re:検討してみます pokopon 2001/07/08-22:33
記事番号12191へのコメント
KHさん こんばんは

色々と参考となるご意見をいただきましてありがとうございました。

>タイムラグ確かにあります。ファイルロックは共有状態の場合で、専有で開いた場合はありませ
>ん。専有でもクライアントが終了直後、隣のクライアントが少し待たされる事はあります。
>ネットワークシステム(ネットウエアーやWIN)が交通整理に時間がかかっているのだと思い
>ます。
ファイルが使用中かどうか判断するのはサーバー側ではないですよね。
クライアント側ですよね。
クライアント側が「空いている」と判断していても、実際に瞬時に誰かによって開かれた場合、
クライアント側では「開いている」と判断されている・・・・これが、タイムラグに該当するのでしょうか?
むしろ、だれも「開いていない」のに「開いている」とクライアント側で判断しているために、ループ脱出が
不可能=「見かけのフリーズ」となっているのではないか? と思っています。
ファイルロックというのは「表の共有状態」の意味ではなく、見かけ上、そのような現象だから・・・・という意味で書きました。

1 繰り返し
2    条件 ( #ファイル使用( &LogFile , 1) = 1 ) 繰り返し中止
3 繰り返し終了
4 表 &LogFile ,モード="専有" , 終了状態 = &RES
5 ケース開始
6  ケース (&RES=1)
7     編集表 &LogFile
8     行追加 [Date]=#DATE , [Time]=#Time , [User]=#ユーザ,[Mode]=&MODE
9     終了 表 編集対象表
10 ケース終了

上記の中で、2行目の #ファイル使用 で「ファイルは開かれていない」と判断してから、
次の4行目に移行するとき、ちょっとしたタイミングで(移行時間内で)別のユーザーによって表が開かれたとしても、
表を開けなかった場合には、その後の「ケース」移行の行はスキップされている筈ですよね。
エラーの原因は何かしらの理由で、表は開かれていないのに「開かれている」と判断され、「1〜3行目」をループしつづけるからかと思われます。
その場合には、「別に開いた誰かが本当のフリーズ状態」になっています。

アルゴリズム上の改善で、何とか解決を図りたいと思っています。

>LOGファイルの行数は制限無く限界まで残しておくのですか?かなり大きくなっているのでは?
>ログファイルの行数を制限して自動的に古い行を削除するとか、月ごとにLOGファイルを分け
>るとか・・・

ご指摘のとおりでした。LOG用のファイルは膨れるばかりです。
ですので、使う度にファイルのオープンに時間がかかるようです。
2日間で1600件も登録があります。
日ごと程度にLOGファイルを切り替えるようにしてみたいと思います。
開発当初は、これほどのアクセスがあるとは予想してはいませんでしたので。

>それでも解決しないのなら、
>やはり、フォームを開く時に共有更新状態でLOGファイルを開くのが早道では(pokoponさん
>が意図している方向を無視してゴメンなさい)ないかと思います。
残念ながら、それはできません。やりたくてもできないのが実情です。とほほ・・・・。

>少なくてもフリ−ズ状態には
>ならないと思います。処理選択のボタンを押下した時点(正確には該当の処理をするために表が
>開けた時、はねられたら書き込まない)で、時間と作業内容を書き込むようにすれば解消すると
>思いますが。
>
上記のコマンドは、ボタンが押下された時に実行するイベントに記述しています。
ネックは、「表の状態を検査」したあと、「表を実際に開く」までのタイムラグに起因のではなかと予想しています。

あまり桐とは関係ありませんが、WEB上で「掲示板」などのスクリプト(CGI)でよく行う「ファイルロック」の記述を参考にして作ったつもりですが、
どうも??? なのです。
すなわち、ファイルに書き込んでいる(記録している)最中は、「他のユーザに待ってもらう方式」なのですが。
「掲示板」等の書き込みの際には、意外ときちんとこの処理がされており、「書き込みエラー」はめったに発生しませんよね。
それとおなじ作業を「桐」の中でしたいという事です。

アルゴリズムに問題があるのかなと思っています。

何でも構いませんので、またレスをつけて下されば幸いです。

12243 Re:解決編ではありませんけど・・・・ pokopon 2001/07/12-06:53
記事番号12187へのコメント
皆様からいろいろとご意見をいただきました。
完全なる解決編ではありませんが、「エラーの少ない」方法の一つを提案します。

>このファイルロック&書き込みのループは次のように記述しています。
>
> 繰り返し
>    条件 ( #ファイル使用( &LogFile , 1) = 1 ) 繰り返し中止
> 繰り返し終了
> 表 &LogFile ,モード="専有" , 終了状態 = &OK
> ケース開始
>  ケース (&RES=1)
>     編集表 &LogFile
>     行追加 [Date]=#DATE , [Time]=#Time , [User]=#ユーザ名 ,
>[File]=&処理 , [Mode]=&MODE
>     終了 表 編集対象表
> ケース終了

最初は、上記のようでしたが、
1.ファイルの状態を確認して、OKであっても、次のステップで「開ける」保証は無い。
  すなわち、「無駄」。
2.無限ループ(デットロック)を防ぐ手立てをすべき
3.桐ファイルでの管理では、桐ファイルの読み込みのための時間がかかるので、印字により、TXTファイルで管理する。

これで、結構、調子よくできそうです。

手続き定義開始 LOG書き込み(文字列 &MODE , 参照 整数 &OK)
 &OK = 0
 繰り返し &N = 1 , &COUNT
   印字開始 &LogFile , 追加 , 終了状態 = &OK
   条件 ( &OK = 1 ) 印字 #DATE,",",#Time,",",#ユーザ名,&MODE
   印字終了
   条件 ( &OK = 1 ) 繰り返し中止
 繰り返し終了
 条件 ( &OK <> 1) メッセージボックス ログ書き込みエラー , "ログの書き込みに失敗しました。
\n\nネットワーク管理者にエラーの状況を報告して下さい。\n\nそのまま処理を続けます。" , 制御文字展開 = する
 手続き定義終了

&COUNTは、混み具合で調整します。私の場合には20程度としました。運用しながら、かえていく必要があると思います。
TXTへの書き出し(印字)は「一瞬」でした。タイムラグも最小限に防げそうです。
ちなみに、「LOGファイルが開けなかった」場合でも「印字終了」はエラーにはなりません。
それは「印字終了」コマンドが、「ファイルを開けなかった場合」には「何もしない」のだそうです。

以上、参考までに。


12249 Re:フォーム利用状況のログを取る方法 Ogo 2001/07/12-12:06
記事番号12187へのコメント

正攻法のみを考えず、回避方法を行く種類も考えてみてはいかがですか?

案1.ログをローカルに取る方法。
   最終的にマージする方法が問題だが。

案2.ログファイル名を、共有が発生し得ないユニークな
   ファイル名にする。
   あ〜、これが最も現実的か。

   ログファイルはテキストとし、その名前は、

 日時+ログオン名(またはローカルマシン名)+".txt" 等

   とし、必ずユニークなファイル名をサーバーの共有フォルダに新規作成する(もちろん、 CSV でも K3でも OK )。

   その上で、サーバー側で桐の一括処理を走らせれば問題は消える。

   サーバーで走らせる桐の一括処理とは、単なるログ
   収集無限ループのみ( Exit 方法を準備しておく事)。

   1.サーバーの共有フォルダで「*.txt(*.CSV,*.K3)」を #ファイル検索 する。

   2.上記が存在した場合、ログ記録用 *.TBL を開き、見つけたファイルを読み込む。

   3.読み込み終了後、当該テキストファイルを削除。

# 問題はレスポンスですね。上記ループ速度よりも、ログオン
# 回数が多ければ、大変な事になるかも。

# なお、# ファイル検索 をする時に、できるだけログオン順
# に近くなるようにするためには、書き出すファイル名は日時
# が最初に来るようにした方がいいと思う(#ファイル検索で
# 入手したファイル名を、更にファイル名でソートする手順が
# あった方がベターなのでしょう)。


12258 Re:フォーム利用状況のログを取る方法 pokopon 2001/07/12-16:31
記事番号12249へのコメント
Ogoさん こんにちは

>正攻法のみを考えず、回避方法を行く種類も考えてみては
>いかがですか?
>案1.ログをローカルに取る方法。
>   最終的にマージする方法が問題だが。
>案2.ログファイル名を、共有が発生し得ないユニークな
>   ファイル名にする。
>   あ〜、これが最も現実的か。
>   ログファイルはテキストとし、その名前は、
> 日時+ログオン名(またはローカルマシン名)+".txt" 等
>   とし、必ずユニークなファイル名をサーバーの共有
>   フォルダに新規作成する(もちろん、 CSV でも K3
>   でも OK )。

確かに案2が現実的ですね。参考になりました。
これだと、ファイルのバッチングは発生しませんね。
「ローカルにデータを置く」は、こちらのクライアントの性質上? ちょっと難しいです。

案2も検討させていただきます。1箇所にLOGを集めておけば、集計は簡単ですから。

ご意見、ありがとうございました。

戻る