001/* 002 * Copyright (c) 2009 The openGion Project. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 013 * either express or implied. See the License for the specific language 014 * governing permissions and limitations under the License. 015 */ 016package org.opengion.fukurou.process; 017 018import org.opengion.fukurou.util.Argument; 019import org.opengion.fukurou.util.Closer ; 020import org.opengion.fukurou.util.FileUtil ; 021import org.opengion.fukurou.util.StringUtil ; 022import org.opengion.fukurou.util.LogWriter; 023import org.opengion.fukurou.mail.MailTX ; 024 025import java.util.Map ; 026import java.util.LinkedHashMap ; 027import java.io.PrintWriter ; 028import java.io.StringWriter ; 029 030/** 031 * Process_Logger は、画面出力、ファイルログ、エラーメールを管理する、 032 * ロギング関係の LoggerProcess インターフェースの実装クラスです。 033 * 034 * MainProcess で使用されるログと、各種 Process で使用されるディスプレイを 035 * 管理します。また、エラー発生時の、メール送信機能も、ここで用意します。 036 * 037 * 引数文字列中にスペースを含む場合は、ダブルコーテーション("") で括って下さい。 038 * 引数文字列の 『=』の前後には、スペースは挟めません。必ず、-key=value の様に 039 * 繋げてください。 040 * 041 * @og.formSample 042 * Process_Logger -logFile=ABC.txt -dispFile=System.out 043 * 044 * [ -logFile=ログ出力先指定 ] : -logFile=[ファイル名/System.out/System.err] (初期値:null) 045 * [ -dispFile=画面出力先指定 ] : -dispFile=[ファイル名/System.out/System.err](初期値:null) 046 * [ -host=メールサーバ ] : -host=メールサーバー 047 * [ -from=送信From ] : -from=送信元アドレス 048 * [ -to=受信To ] : -to=送信先アドレスをカンマ区切りで並べる 049 * [ -charset=キャラクタセット ] : -charset=メール送信時のキャラクタセット [ISO-2022-JP / Windows-31J] 050 * [ -subject=タイトル ] : -subject=タイトル 051 * [ -message=本文雛形 ] : -message=本文雛形文章 052 * [ -msgFile=本文雛形ファイル ] : -msgFile=本文を格納しているファイルのアドレス 053 * [ -{@XXXX}=YYYY ] : メッセージ本文の {@XXXX} 文字列を、YYYY 文字列に変換します。 054 * 055 * @version 4.0 056 * @author Kazuhiko Hasegawa 057 * @since JDK5.0, 058 */ 059public class Process_Logger extends AbstractProcess implements LoggerProcess { 060 061 private String logFile = null; // ログ出力先 062 private String dispFile = null; // 画面出力先 063 064 private PrintWriter logWriter = null; 065 private PrintWriter dispWriter = null; 066 067 /** メール送信時のデフォルトキャラクタセット {@value} */ 068 public static final String DEFAULT_CHARSET = "ISO-2022-JP" ; 069 private String host = "mail.opengion.org"; 070 private String from = "DUMMY@DUMMY"; 071 private String to = null; 072 private String subject = null; // 5.3.1.0 (2011/03/10) 073 private boolean useErrMail = false; 074 075 private static final Map<String,String> mustProparty ; // [プロパティ]必須チェック用 Map 076 private static final Map<String,String> usableProparty ; // [プロパティ]整合性チェック Map 077 078 static { 079 mustProparty = new LinkedHashMap<String,String>(); 080 081 usableProparty = new LinkedHashMap<String,String>(); 082 usableProparty.put( "logFile", "ログ出力先指定のファイル名を指定します(初期値:null)" + 083 CR + "『System.out』,『System.err』は特殊な名称です。" ); 084 usableProparty.put( "dispFile", "画面出力先指定のファイル名を指定します(初期値:null)" + 085 CR + "『System.out』,『System.err』は特殊な名称です。" ); 086 usableProparty.put( "host", "メールサーバー" ); 087 usableProparty.put( "from", "送信元アドレス" ); 088 usableProparty.put( "to", "送信先アドレスをカンマ区切りで並べる" ); 089 usableProparty.put( "charset", "メール送信時のキャラクタセット [ISO-2022-JP / Windows-31J]" ); 090 usableProparty.put( "subject", "タイトル" ); 091 usableProparty.put( "message", "本文雛形文章" ); 092 usableProparty.put( "msgFile", "本文雛形を格納しているファイルのアドレス" ); 093 usableProparty.put( "{@", "{@XXXX}=YYYY 汎用文字変換" + 094 CR + "メッセージ本文の {@XXXX} 文字列を、YYYY 文字列に変換します。" ); 095 usableProparty.put( "{@ARG.", "{@ARG.XXX} 予約文字変換 上記引数を割り当てます。" ); 096 usableProparty.put( "{@DATE.", "{@DATE.XXX} 予約文字変換 の文字を変換します。" + 097 CR + "(SimpleDateFormat 形式の日付、時刻等)" ); 098 usableProparty.put( "{@ENV.", "{@ENV.XXX} 予約文字変換 システムプロパティーの文字を変換します。" + 099 CR + "(java -Dkey=value オプションで引き渡します。)" ); 100 } 101 102 /** 103 * デフォルトコンストラクター。 104 * このクラスは、動的作成されます。デフォルトコンストラクターで、 105 * super クラスに対して、必要な初期化を行っておきます。 106 * 107 */ 108 public Process_Logger() { 109 super( "org.opengion.fukurou.process.Process_Logger",mustProparty,usableProparty ); 110 } 111 112 /** 113 * プロセスの初期化を行います。初めに一度だけ、呼び出されます。 114 * 初期処理(ファイルオープン、DBオープン等)に使用します。 115 * 116 * @og.rev 5.3.4.0 (2011/04/01) タイトル追加 117 * 118 * @param paramProcess データベースの接続先情報などを持っているオブジェクト 119 */ 120 public void init( final ParamProcess paramProcess ) { 121 Argument arg = getArgument(); 122 123 logFile = arg.getProparty( "logFile" ); // ログ出力先 124 dispFile = arg.getProparty( "dispFile" ); // 画面出力先 125 126 if( logWriter == null && logFile != null ) { 127 logWriter = FileUtil.getLogWriter( logFile ); 128 } 129 130 if( dispWriter == null && dispFile != null ) { 131 dispWriter = FileUtil.getLogWriter( dispFile ); 132 } 133 134 host = arg.getProparty( "host",host ); // メールサーバー 135 from = arg.getProparty( "from",from ); // 送信元アドレス 136 to = arg.getProparty( "to" ,to ); // 送信先アドレス 137 subject = arg.getProparty( "subject" ); // 5.3.4.0 (2011/04/01) タイトル 138 useErrMail = host != null && from != null && to != null ; 139 } 140 141 /** 142 * プロセスの終了を行います。最後に一度だけ、呼び出されます。 143 * 終了処理(ファイルクローズ、DBクローズ等)に使用します。 144 * 145 * @param isOK トータルで、OKだったかどうか[true:成功/false:失敗] 146 */ 147 public void end( final boolean isOK ) { 148 if( logWriter != null ) { 149 logWriter.flush(); 150 Closer.ioClose( logWriter ); 151 } 152 153 if( dispWriter != null ) { 154 dispWriter.flush(); 155 Closer.ioClose( dispWriter ); 156 } 157 } 158 159 /** 160 * ログファイルにメッセージを表示します。 161 * 162 * @param msg 表示するメッセージ 163 */ 164 @Override 165 public void logging( final String msg ) { 166 if( logWriter != null ) { 167 logWriter.println( msg ) ; 168 } 169 } 170 171 /** 172 * ディスプレイにメッセージを表示します。 173 * 174 * @param msg 表示するメッセージ 175 */ 176 @Override 177 public void println( final String msg ) { 178 if( dispWriter != null ) { 179 dispWriter.println( msg ) ; 180 } 181 } 182 183 /** 184 * エラーログにメッセージを表示します。 185 * ここに書き込まれたメッセージは、通常ログと、特殊ログの 186 * 両方に書き込まれます。 187 * 特殊ログとは、メール連絡等のことです。 188 * 189 * @param msg 表示するメッセージ 190 * @param th Throwable例外オブジェクト 191 */ 192 public void errLog( final String msg,final Throwable th ) { 193 String sendMsg = msg; 194 if( logWriter != null ) { 195 if( th != null ) { 196 StringWriter errMsg = new StringWriter(); 197 errMsg.append( msg ).append( CR ); 198 th.printStackTrace( new PrintWriter( errMsg ) ); 199 sendMsg = errMsg.toString(); 200 } 201 logWriter.println( sendMsg ) ; 202 } 203 println( sendMsg ) ; 204 if( useErrMail ) { sendmail( sendMsg ) ; } 205 } 206 207 /** 208 * メール送信を行います。 209 * 210 * @og.rev 5.3.4.0 (2011/04/01) タイトル追加 211 * 212 * @param msg 送信するメッセージ 213 */ 214 private void sendmail( final String msg ) { 215 216 Argument arg = getArgument(); 217 218 String charset = arg.getProparty( "charset", DEFAULT_CHARSET ); 219 MailTX mail = new MailTX( host,charset ); 220 mail.setFrom( from ); 221 mail.setTo( StringUtil.csv2Array( to ) ); 222 mail.setSubject( subject ); // 5.3.4.0 (2011/04/01) 223 224 String message = arg.getFileProparty("message","msgFile",false); 225 226 // {@XXX} 変換は、Argument クラスの機能を使う。 227 message = arg.changeParam( message ); 228 message = message + CR + msg ; 229 mail.setMessage( message ); 230 mail.sendmail(); 231 } 232 233 /** 234 * ログ出力用のPrintWriterを設定します。 235 * 通常は、引数の -logFile=XXXX で指定しますが、直接 PrintWriter を 236 * 渡す必要があるケース(JSPなどで使用するケース)で使用します。 237 * 引数より、こちらの設定のほうが、優先されます。 238 * ※ JspWriter を渡す場合の PrintWriter は、flushing および、close 処理を 239 * 行わない NonFlushPrintWriter を設定してください。 240 * 241 * @param logWriter ログ出力用のPrintWriter 242 */ 243 public void setLoggingWriter( final PrintWriter logWriter ) { 244 this.logWriter = logWriter; 245 } 246 247 /** 248 * 画面表示用のPrintWriterを設定します。 249 * 通常は、引数の -dispFile=XXXX で指定しますが、直接 PrintWriter を 250 * 渡す必要があるケース(JSPなどで使用するケース)で使用します。 251 * 引数より、こちらの設定のほうが、優先されます。 252 * ※ JspWriter を渡す場合の PrintWriter は、flushing および、close 処理を 253 * 行わない NonFlushPrintWriter を設定してください。 254 * 255 * @param dispWriter 画面表示用のPrintWriter 256 */ 257 public void setDisplayWriter( final PrintWriter dispWriter ) { 258 this.dispWriter = dispWriter; 259 } 260 261 /** 262 * プロセスの処理結果のレポート表現を返します。 263 * 処理プログラム名、入力件数、出力件数などの情報です。 264 * この文字列をそのまま、標準出力に出すことで、結果レポートと出来るような 265 * 形式で出してください。 266 * 267 * @og.rev 5.3.4.0 (2011/04/01) タイトル追加 268 * 269 * @return 処理結果のレポート 270 */ 271 public String report() { 272 return "[" + getClass().getName() + "]" + CR 273 + TAB + "Subject : " + subject + CR 274 + TAB + "Log File : " + logFile + CR 275 + TAB + "Display File : " + dispFile ; 276 } 277 278 /** 279 * このクラスの使用方法を返します。 280 * 281 * @return このクラスの使用方法 282 */ 283 public String usage() { 284 StringBuilder buf = new StringBuilder(); 285 286 buf.append( "Process_Logger は、画面出力、ファイルログ、エラーメールを管理する、" ).append( CR ); 287 buf.append( "ロギング関係の LoggerProcess インターフェースの実装クラスです。" ).append( CR ); 288 buf.append( CR ); 289 buf.append( "MainProcess で使用されるログと、各種 Process で使用されるディスプレイを" ).append( CR ); 290 buf.append( "管理します。また、エラー発生時の、メール送信機能も、ここで用意します。" ).append( CR ); 291 buf.append( CR ); 292 buf.append( "引数文字列中に空白を含む場合は、ダブルコーテーション(\"\") で括って下さい。" ).append( CR ); 293 buf.append( "引数文字列の 『=』の前後には、空白は挟めません。必ず、-key=value の様に" ).append( CR ); 294 buf.append( "繋げてください。" ).append( CR ); 295 buf.append( CR ).append( CR ); 296 297 buf.append( getArgument().usage() ).append( CR ); 298 299 return buf.toString(); 300 } 301 302 /** 303 * このクラスは、main メソッドから実行できません。 304 * 305 * @param args コマンド引数配列 306 */ 307 public static void main( final String[] args ) { 308 LogWriter.log( new Process_Logger().usage() ); 309 } 310}