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.system; // 6.4.2.0 (2016/01/29) package変更 fukurou.util → fukurou.system 017 018// import java.io.BufferedWriter; // 8.5.4.2 (2024/01/12) 019import java.io.File; 020// import java.io.FileWriter; // 8.5.4.2 (2024/01/12) 021import java.io.IOException; 022import java.io.PrintWriter; 023 024import java.nio.file.Files; // 8.5.4.2 (2024/01/12) PMD 7.0.0 AvoidFileStream 対応 025import java.nio.charset.Charset; // 8.5.4.2 (2024/01/12) PMD 7.0.0 AvoidFileStream 対応 026import java.nio.file.OpenOption; // 8.5.4.2 (2024/01/12) PMD 7.0.0 AvoidFileStream 対応 027import java.nio.file.StandardOpenOption; // 8.5.4.2 (2024/01/12) PMD 7.0.0 AvoidFileStream 対応 028 029// import java.io.OutputStreamWriter; // 7.1.0.1 (2020/02/07) 8.5.4.2 (2024/01/12) delete 030// import java.io.FileOutputStream; // 7.1.0.1 (2020/02/07) 8.5.4.2 (2024/01/12) delete 031 032/** 033 * Logを書き込む為の PrintWriter を管理するクラスです。 034 * 035 * 実際の Log の書き込みには、LogSender を利用して下さい。 036 * 037 * @og.rev 6.4.2.0 (2016/01/29) package変更 fukurou.util → fukurou.system 038 * 039 * @og.group エラー処理 040 * 041 * @version 4.0 042 * @author Kazuhiko Hasegawa 043 * @since JDK5.0, 044 */ 045public final class LogWriter { 046 private static PrintWriter writer ; 047 private static String encode ; // 7.1.0.1 (2020/02/07) "UTF-8" など 048 private static final Object LOCK = new Object(); // 6.3.9.0 (2015/11/06) synchronizedブロック 049 050 private static String logFileUrl ; // 4.1.0.1 (2008/01/23) 051 052 // 8.5.4.2 (2024/01/12) PMD 7.0.0 AvoidFileStream 対応 053 private static final OpenOption[] APPEND = { StandardOpenOption.WRITE , StandardOpenOption.CREATE , StandardOpenOption.APPEND }; 054 055 /** 056 * デフォルトコンストラクターをprivateにして、 057 * オブジェクトの生成をさせないようにする。 058 * 059 */ 060 private LogWriter() {} 061 062 /** 063 * Logファイルの出力先を設定します。 064 * 065 * このファイル名は、日付フォーマット変数を含むことができます。 066 * 067 * @og.rev 4.1.0.1 (2008/01/23) 新規作成 068 * @og.rev 6.3.9.0 (2015/11/06) Use block level rather than method level synchronization.(PMD) 069 * @og.rev 6.4.2.0 (2016/01/29) 出力先変更時は、既存の Writer をclose() してからにする。 070 * @og.rev 7.1.0.1 (2020/02/07) ログファイルのエンコードを指定します。 071 * 072 * @param url 出力先 073 * @param enc エンコード 074 * @see org.opengion.fukurou.system.DateSet#changeString(String) 075 */ 076// public static void init( final String url ) { 077 public static void init( final String url,final String enc ) { 078 synchronized( LOCK ) { 079 close(); 080 logFileUrl = url; 081 encode = enc; // 7.1.0.1 (2020/02/07) 082 } 083 } 084 085 /** 086 * Logを書き出します。 087 * 088 * @og.rev 4.1.0.1 (2008/01/23) 出力時間を出力する。 089 * @og.rev 5.5.7.2 (2012/10/09) HybsDateUtil を利用するように修正します。 090 * @og.rev 6.3.9.0 (2015/11/06) Use block level rather than method level synchronization.(PMD) 091 * 092 * @param message メッセージ 093 */ 094 public static void log( final String message ) { 095 synchronized( LOCK ) { 096 if( writer == null ) { writer = getPrintWriter(); } 097 } 098 writer.println( "[WriteTime= " + DateSet.getDate( "yyyy/MM/dd HH:mm:ss.SSS" ) + "] " + message ); // 5.5.7.2 (2012/10/09) HybsDateUtil を利用 099 writer.flush(); 100 } 101 102 /** 103 * 例外のスタックトレースをLogWriterのPrintWriterに書き出します。 104 * 105 * @og.rev 4.1.0.1 (2008/01/23) 新規作成 106 * @og.rev 4.3.4.5 (2009/01/08) nullチェック追加 107 * @og.rev 6.3.9.0 (2015/11/06) Use block level rather than method level synchronization.(PMD) 108 * @og.rev 6.4.2.0 (2016/01/29) ex.printStackTrace() を、ThrowUtil#ogStackTrace(Throwable) に置き換え。 109 * 110 * @param th スタックトレースの取得元Throwableオブジェクト 111 */ 112 public static void log( final Throwable th ) { 113 synchronized( LOCK ) { 114 if( writer == null ) { writer = getPrintWriter(); } 115 } 116 writer.println( ThrowUtil.ogStackTrace( th ) ); // 6.4.2.0 (2016/01/29) 117 } 118 119 /** 120 * PrintWriter を close() します。 121 * 122 * @og.rev 6.3.9.0 (2015/11/06) Use block level rather than method level synchronization.(PMD) 123 */ 124 public static void close() { 125 synchronized( LOCK ) { 126 if( writer != null ) { writer.close(); } 127 writer = null; 128 } 129 } 130 131 /** 132 * 追加モードで作成した PrintWriter を取得します。 133 * PrintWriter は、シングルトーンとして唯一存在させています。 134 * 135 * @og.rev 4.1.0.1 (2008/01/23) ログファイル出力先を外部から指定する。 136 * @og.rev 6.3.9.0 (2015/11/06) Use block level rather than method level synchronization.(PMD) 137 * @og.rev 7.1.0.1 (2020/02/07) ログファイルのエンコードを指定します。 138 * @og.rev 8.5.5.1 (2024/02/29) PrintWriter 作成で、autoFlush を true にする。 139 * 140 * @return 追加モードで作成したPrintWriter 141 * @og.rtnNotNull 142 */ 143 private static PrintWriter getPrintWriter() { 144 // 8.5.5.1 (2024/02/29) PMD 7.0.0 OnlyOneReturn メソッドには終了ポイントが 1 つだけ必要 145 if( logFileUrl == null || logFileUrl.isEmpty() ) { 146 return new PrintWriter( System.err ); 147 } 148// else { 149 150 // 日付フォームのファイル名を変換します。 151 final DateSet dateSet = new DateSet(); 152 final String timeFileUrl = dateSet.changeString( logFileUrl ); // 6.3.9.0 (2015/11/06) 日付フォーマットは、作成都度行う事とする。 153 154 try { 155 final File logFile = new File( timeFileUrl ); 156 // 7.1.0.1 (2020/02/07) ログファイルのエンコードを指定します。 157 // return new PrintWriter( new BufferedWriter( new FileWriter( logFile, true ) ) ); 158 return ( encode == null || encode.isEmpty() ) 159 ? new PrintWriter( Files.newBufferedWriter(logFile.toPath(), APPEND ) ) 160 : new PrintWriter( Files.newBufferedWriter(logFile.toPath(), Charset.forName( encode ), APPEND ) ); // 7.1.0.1 (2020/02/07) 161 162// if( encode == null || encode.isEmpty() ) { 163// // 8.5.4.2 (2024/01/12) PMD 7.0.0 AvoidFileStream 対応 164//// return new PrintWriter( new BufferedWriter( new FileWriter( logFile, true ) ) ); 165//// return new PrintWriter( Files.newBufferedWriter(logFile.toPath(), APPEND ) ); 166// rtnWriter = new PrintWriter( Files.newBufferedWriter(logFile.toPath(), APPEND ) ); 167// } 168// else { 169// // 8.5.4.2 (2024/01/12) PMD 7.0.0 AvoidFileStream 対応 170//// return new PrintWriter( new BufferedWriter( new OutputStreamWriter( new FileOutputStream( logFile, true ), encode ) ) ); // 7.1.0.1 (2020/02/07) 171//// return new PrintWriter( Files.newBufferedWriter(logFile.toPath(), Charset.forName( encode ), APPEND ) ); // 7.1.0.1 (2020/02/07) 172// rtnWriter = new PrintWriter( Files.newBufferedWriter(logFile.toPath(), Charset.forName( encode ), APPEND ) ); // 7.1.0.1 (2020/02/07) 173// } 174 } 175 catch( final IOException ex ) { 176 final String errMsg = "ログライターが作成できません。[" + timeFileUrl + "]"; 177 throw new OgRuntimeException( errMsg, ex ); 178 } 179// } 180 } 181}