001/* 002 * Copyright (c) 2017 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.fileexec; 017 018// import java.nio.file.Paths; // 6.8.1.5 (2017/09/08) 019 020import java.util.logging.Logger; 021import java.util.logging.Level; 022import java.util.function.Supplier; // 6.8.1.0 (2017/07/14) 023import java.util.function.Function; // 7.2.5.0 (2020/06/01) 024 025/** 026 * XLoggerは、Throwable を引数に取るwarningと、Level 600 の debug メソッドを 027 * 持つ、Logger の拡張クラスです。 028 * ここでは、継承するのではなく、委譲で、最低限のメソッドだけに対応しています。 029 * (LogManager とか、色々とややこしそうなので、調査する暇が無い) 030 * 031 * WARNING(900) → INFO(800) → CONFIG(700) → XXXX(600) → FINE(500) → ALL(Integer.MIN_VALUE) 032 * となっていますが、FINE では、多すぎ、INFO は、通常使用、間に、DEBUG的な、 033 * ロギングが欲しい場合に使用します。 034 * CONFIG を使いたいところですが、「CONFIGは静的な構成メッセージのメッセージ・レベルです。」と 035 * JavaDocにわざわざ、書かれていることから、使用を避けます。 036 * 037 * @og.rev 7.0.0.0 (2017/07/07) 新規作成 038 * 039 * @version 7.0 040 * @author Kazuhiko Hasegawa 041 * @since JDK1.8, 042 */ 043public class XLogger { 044 // 7.2.5.0 (2020/06/01) 各クラスで、class.getSimpleName() を渡すようにしたので短縮不要。 045// /** 初期設定されているリソースバンドルのbaseName {@value} */ 046// public static final String OMIT_NAME = "org.opengion.fukurou." ; // fileexec は残す 047 048 /** 049 * デバッグレベルを新規に定義します。 050 * 051 * OFF:Integer.MAX_VALUE , SEVERE:1000 , WARNING:900 , INFO:800 , CONFIG:700 , FINE:500 , FINER:400 , FINEST:300 , ALL:Integer.MIN_VALUE 052 * LEVEL_DEBUG:600 で定義することで、INFO より細かいが、FINE より荒いログ出力が可能です。 053 * 他のアプリケーションで、INFO は許せても、FINE は許せない場合があるので、独自のログ出力が、可能です。 054 */ 055 private static final class LEVEL_DEBUG extends Level { 056 private static final long serialVersionUID = 681020170714L ; // 6.8.1.0 (2017/07/14) 057 /** 058 * デバッグレベルのコンストラクター 059 */ 060 public LEVEL_DEBUG() { super( "DEBUG",600 ); } 061 }; 062 063// private static final Level DEBUG = new LEVEL_DEBUG(); 064 private static final Level L_DEBUG = new LEVEL_DEBUG(); // 6.9.7.0 (2018/05/14) PMD Field DEBUG has the same name as a method 065 066 private final Logger LOGGER; 067 068 /** 069 * 名前を指定して、XLoggerオブジェクトを作成します。 070 * 071 * @og.rev 6.8.1.5 (2017/09/08) logフォルダの存在チェックと作成 072 * 073 * @param name ロガーの名前。通常は、クラス.class.getName() を渡せばよいです。 074 */ 075 private XLogger( final String name ) { 076// FileUtil.mkdirs( Paths.get( "log" ) ); // Logger の log フォルダが無ければ作成します。 077 078 LOGGER = Logger.getLogger( name ); 079 } 080 081 /** 082 * 名前を指定して、XLoggerオブジェクトを作成します。 083 * 084 * @og.rev 7.2.1.0 (2020/03/13) ロガーの名前から、共通部分を削除します。 085 * @og.rev 7.2.5.0 (2020/06/01) 各クラスで、class.getSimpleName() を渡すようにした。 086 * 087 * @param name ロガーの名前。通常は、クラス.class.getName() を渡せばよいです。 088 * @return XLoggerオブジェクト 089 */ 090 public static XLogger getLogger( final String name ) { 091// String key = name ; 092// if( key.startsWith( OMIT_NAME ) ) { 093// key = name.substring( OMIT_NAME.length() ); 094// } 095 096// return new XLogger( name ); // 今は、個別に作成していますが、本来は、同じオブジェクトを返すようにすべき。 097 return new XLogger( name ); // 各クラスで static で持つのでキャッシュしません。 098 } 099 100 /** 101 * INFO レベルのログをとります。 102 * 103 * 引数は Supplier のみなので、実行直前まで処理されません。 104 * よって、呼出元では、log level guards する必要はありません。 105 * 106 * @og.rev 7.3.0.0 (2021/01/06) PMD:GuardLogStatement: Logger calls should be surrounded by log level guards. 107 * 108 * @param msgSupplier 呼び出されると、目的のログ・メッセージを生成する関数 109 * @see Logger#info( Supplier ) 110 */ 111 public void info( final Supplier<String> msgSupplier ) { 112 if( LOGGER.isLoggable( Level.INFO ) ) { 113 LOGGER.info( msgSupplier ); 114 } 115 } 116 117 /** 118 * WARNING レベルのログをとります。 119 * 120 * 引数は Supplier のみなので、実行直前まで処理されません。 121 * よって、呼出元では、log level guards する必要はありません。 122 * 123 * @og.rev 7.3.0.0 (2021/01/06) PMD:GuardLogStatement: Logger calls should be surrounded by log level guards. 124 * 125 * @param msgSupplier 呼び出されると、目的のログ・メッセージを生成する関数 126 * @see Logger#warning( Supplier ) 127 */ 128 public void warning( final Supplier<String> msgSupplier ) { 129 if( LOGGER.isLoggable( Level.WARNING ) ) { 130 LOGGER.warning( msgSupplier ); 131 } 132 } 133 134 /** 135 * WARNING レベルのログが、処理されるか、判定します。 136 * 137 * 引数が Supplier のみでない場合は、実行前に、log level guards してください。 138 * 139 * @og.rev 7.3.0.0 (2021/01/06) 新規追加 140 * 141 * @return args WARNINGレベルのログを出力する場合は、trueを返します。 142 */ 143 public boolean isWarningEnabled() { 144 return LOGGER.isLoggable( Level.WARNING ); 145 } 146 147 /** 148 * WARNING レベルのログをとります。 149 * 150 * 引数処理が発生しますので、呼出元で、log level guards してください。 151 * 152 * if( XLogger.isWarningEnabled() ) { 153 * XLogger.warning( id,args1,args2,… ); 154 * } 155 * 156 * @og.rev 7.2.5.0 (2020/06/01) メソッド追加。 157 * 158 * @param id リソースのキーとなるID。 159 * @param args リソースを、MessageFormat.format で加工する場合の引数。 160 * @see Logger#warning( Supplier ) 161 */ 162 public void warning( final String id , final Object... args ) { 163 LOGGER.warning( MsgUtil.errPrintln( id,args ) ); 164 } 165 166 /** 167 * WARNING レベルのログをとります。 168 * 169 * これは、Throwable を引数に取る拡張されたメソッドです。 170 * 引数処理が発生しますので、呼出元で、log level guards してください。 171 * 172 * @param th ログ・メッセージに関連したThrowable。 173 * @param msgSupplier 呼び出されると、目的のログ・メッセージを生成する関数 174 * @see Logger#log( Level,Throwable,Supplier ) 175 */ 176 public void warning( final Throwable th , final Supplier<String> msgSupplier ) { 177 LOGGER.log( Level.WARNING , th , msgSupplier ); 178 } 179 180 /** 181 * WARNING レベルのログをとります。 182 * 183 * これは、Throwable を引数に取る拡張されたメソッドです。 184 * 引数処理が発生しますので、呼出元で、log level guards してください。 185 * 186 * @og.rev 7.2.5.0 (2020/06/01) メソッド追加。 187 * 188 * @param th 発生元のThrowable( null値は許容されます ) 189 * @param id リソースのキーとなるID。 190 * @param args リソースを、MessageFormat.format で加工する場合の引数。 191 * @see Logger#log( Level,Throwable,Supplier ) 192 */ 193 public void warning( final Throwable th , final String id , final Object... args ) { 194 LOGGER.log( Level.WARNING , MsgUtil.errPrintln( id,args ) , th ); // 1.4.0 (2019/10/01) StackTraceの重複を避けるため 195 } 196 197 /** 198 * 600 レベルのログをとります。 199 * 200 * Supplierを引数に、Level = 600 のログをとります。 201 * 202 * 引数は Supplier のみなので、実行直前まで処理されません。 203 * よって、呼出元では、log level guards する必要はありません。 204 * 205 * @og.rev 7.3.0.0 (2021/01/06) PMD:GuardLogStatement: Logger calls should be surrounded by log level guards. 206 * 207 * @param msgSupplier 呼び出されると、目的のログ・メッセージを生成する関数 208 * @see Logger#log( Level,Supplier ) 209 */ 210 public void debug( final Supplier<String> msgSupplier ) { 211// LOGGER.log( DEBUG , msgSupplier ); 212 if( LOGGER.isLoggable( L_DEBUG ) ) { 213 LOGGER.log( L_DEBUG , msgSupplier ); 214 } 215 } 216 217 /** 218 * WARNING レベルのログが、処理されるか、判定します。 219 * 220 * 引数が Supplier のみでない場合は、実行前に、log level guards してください。 221 * 222 * @og.rev 7.3.0.0 (2021/01/06) 新規追加 223 * 224 * @return args WARNINGレベルのログを出力する場合は、trueを返します。 225 */ 226 public boolean isDebugEnabled() { 227 return LOGGER.isLoggable( L_DEBUG ); 228 } 229 230 /** 231 * 数値の変数を受け取って表示する、600 レベルのログをとります。 232 * 233 * Supplierを引数に、Level = 600 のログをとります。 234 * 関数型インタフェースは引数にfinal変数しか使えませんが、数値は大抵可変なので 235 * final化せずに、引数として渡すことが出来るようにします。 236 * 引数処理が発生しますので、呼出元で、log level guards してください。 237 * 238 * @og.rev 7.2.5.0 (2020/06/01) メソッド追加。 239 * 240 * @param num 数値引数 241 * @param msgFunction 呼び出されると、目的のログ・メッセージを生成する関数 242 * @see Logger#log( Level,Supplier ) 243 */ 244 public void debug( final int num , final Function<Integer,String> msgFunction ) { 245 LOGGER.log( L_DEBUG , () -> msgFunction.apply( num ) ); 246 } 247}