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