Coverage Report - jp.co.y_net.amm.common.AppLogger
 
Classes in this File Line Coverage Branch Coverage Complexity
AppLogger
0%
0/78
0%
0/38
0
 
 1  
 package jp.co.y_net.amm.common;
 2  
 
 3  
 import org.slf4j.LoggerFactory;
 4  
 
 5  
 /**
 6  
  * 標準のロギングクラス
 7  
  * 
 8  
  * エラーレベルは logback.xml の LEVEL_APP にて定義される。
 9  
  *  ・通常運用中は ERROR レベル
 10  
  *  ・調査中は INFO レベル
 11  
  *  とする。
 12  
  * 
 13  
  * ■ 各開発者による利用方法
 14  
  *  debug, info, error のいずれかのメソッドを使用する。詳しくは、各メソッドのコメントを参照のこと。
 15  
  *  
 16  
  * ■ アプリケーションアーキテクチャからの利用
 17  
  *  アプリケーションのエラーが発生したときは、WicketApplicationクラスから、RequestCycleListenerを経由して呼び出される。
 18  
  *  
 19  
  * ■ 利用のメリット
 20  
  *  ・サーバーの catalina.out, catalina.err にアプリケーション固有のエラーが出力されなくなり、
 21  
  *   /var/log/app/tomcat/~/logs/AppLog に出力され、世代管理される。
 22  
  *  ・ログのレベルを指定できるため、開発時に記述したデバッグメッセージをわざわざ消さなくても良くなる。
 23  
  *  ・logbackを使用しているので、運用中にログ出力レベルの変更が可能。
 24  
  *  
 25  
  * K.inaba 2014/02/01
 26  
  */
 27  0
 public class AppLogger {
 28  
     private static boolean isLocal;
 29  0
     private static org.slf4j.Logger loggerSlf = LoggerFactory.getLogger(AppLogger.class.getName());
 30  
     
 31  
     static {
 32  
         /*
 33  
          * 開発者担当者のOSのユーザ名を列挙する。
 34  
          * ここに記載がある場合に限り、ローカル開発環境とみなして、標準出力(Eclipseのコンソールなど)へ
 35  
          * 出力を行う。
 36  
          */
 37  0
         String debugKeys = ResourceReader.getStringQuick("debug.users");
 38  
         String[] arrayDebugKey;
 39  0
         if(debugKeys == null) {
 40  0
             arrayDebugKey = new String[]{};
 41  0
         } else {
 42  0
             arrayDebugKey = debugKeys.split(",");
 43  
         }
 44  0
         for(String key: arrayDebugKey) {
 45  0
             if (key.trim().equals(System.getenv("USERNAME"))) {
 46  0
                 isLocal = true;
 47  0
                 break;
 48  
             }
 49  
         }
 50  0
     }
 51  
     
 52  
 
 53  
     public static void main(String[] args) throws InterruptedException {
 54  0
         sample();
 55  0
     }
 56  
     /** 利用方法のサンプル */
 57  
     private static void sample() {
 58  0
         String str = "sundata";
 59  0
         AppLogger.debug("変数 str の値 = " + str);
 60  
         
 61  
         /*
 62  
          * Infoレベルは運用中に必要となるかもしれないレベルの出力を担う。
 63  
          * 通常は表示されない。(開発者のコンソールには表示される。)
 64  
          * 運用中に詳細なログが必要となった時に、「LEVEL_APP」property の設定を INFO にすること。
 65  
          */
 66  0
         AppLogger.info("Infoレベルの出力。");
 67  0
         AppLogger.info(new Exception("例外クラスにも対応"));
 68  
         
 69  
         /*
 70  
          * Errorレベルは必ずログに出力される。
 71  
          * Try ~ Catch で活用する。
 72  
          */
 73  0
         AppLogger.error("Errorレベルの出力。");
 74  0
         AppLogger.error(new Exception("例外クラスにも対応"));
 75  
         try {
 76  0
             int[] i = new int[]{1, 2, 3};
 77  0
             if (i[3] == 4) {
 78  0
                 return;
 79  
             }
 80  0
         } catch (Exception e) {
 81  0
             AppLogger.error("配列の操作に失敗", e);
 82  
         }
 83  0
     }
 84  
     public static boolean isDebug() {
 85  0
         return isLocal;
 86  
     }
 87  
     /**
 88  
      * 開発時のみ出力したいログを出力する。
 89  
      * → ローカル環境の標準出力(Eclipseのコンソールなど)にのみ出力される。
 90  
      * 
 91  
      * @param message 出力する文字列
 92  
      */
 93  
     public static void debug(String message) {
 94  0
         if (isLocal) System.out.println("[DEBUG] " + toPlace(getFromStack()) + "\n" + toString(message));
 95  0
     }
 96  
     /**
 97  
      * 何らかのエラーが発生した時に、調査の参考となるログを出力する。
 98  
      * → logback.xml LEVEL_APP が INFO であれば、/var/log/app/tomcat/~/logs/AppLog に出力される。
 99  
      * → ローカル環境の標準出力(Eclipseのコンソールなど)にも出力される。
 100  
      *
 101  
      * 【ログの出力先】
 102  
      *   Eclipse : プロジェクト直下 sdc/logs/AppLog.yyyy-mm-dd
 103  
      *   Linux:%Tomcatインスタンス%/logs/AppLog.yyyy-mm-dd
 104  
      * 
 105  
      * @param message 出力する文字列
 106  
      */
 107  
     public static void info(String message) {
 108  0
         if (isLocal) System.out.println("[INFO ] " + toPlace(getFromStack()) + "\n" + toString(message));
 109  0
         loggerSlf.info(toPlace(getFromStack()) + "\n" + toString(message));
 110  0
     }
 111  
     /**
 112  
      * @see AppLogger#info(String)
 113  
      * @param exception 出力する例外クラス
 114  
      */
 115  
     public static void info(Throwable exception) {
 116  0
         if (isLocal) System.out.println("[INFO ] " + toPlace(getFromStack()) + "\n" + toString(exception));
 117  0
         loggerSlf.info(toPlace(getFromStack()) + "\n" + toString(exception));
 118  0
     }
 119  
     /**
 120  
      * @see AppLogger#info(String)
 121  
      * @param message 出力する文字列
 122  
      * @param exception 出力する例外クラス
 123  
      */
 124  
     public static void info(String message, Throwable exception) {
 125  0
         if (isLocal) System.out.println("[INFO ] " + toPlace(getFromStack()) + "\n" + toString(message));
 126  0
         if (isLocal) System.out.println("[INFO ] " + toPlace(getFromStack()) + "\n" + toString(exception));
 127  0
         loggerSlf.info(toPlace(getFromStack()) + "\n" + toString(message));
 128  0
         loggerSlf.info(toPlace(getFromStack()) + "\n" + toString(exception));
 129  0
     }
 130  
     /**
 131  
      * Try ~ Catch などで使用する。System.err.println の代用。
 132  
      * @param message 出力する文字列
 133  
      */
 134  
     public static void error(String message) {
 135  0
         if (isLocal) System.out.println("[ERROR] " + toPlace(getFromStack()) + "\n" + toString(message));
 136  0
         loggerSlf.error(toPlace(getFromStack()) + "\n" + toString(message));
 137  0
     }
 138  
     /**
 139  
      * Try ~ Catch などで使用する。e.printStackTrace();の代用
 140  
      * @param exception 出力する例外クラス
 141  
      */
 142  
     public static void error(Throwable exception) {
 143  0
         if (isLocal) System.out.println("[ERROR] " + toPlace(getFromStack()) + "\n" + toString(exception));
 144  0
         loggerSlf.error(toPlace(getFromStack()) + "\n" + toString(exception));
 145  0
     }
 146  
     /**
 147  
      * @param message 
 148  
      * @param exception 
 149  
      */
 150  
     public static void error(String message, Throwable exception) {
 151  0
         if (isLocal) System.out.println("[ERROR] " + toPlace(getFromStack()) + "\n" + toString(message));
 152  0
         if (isLocal) System.out.println("[ERROR] " + toPlace(getFromStack()) + "\n" + toString(exception));
 153  0
         loggerSlf.error(toPlace(getFromStack()) + "\n" + toString(message));
 154  0
         loggerSlf.error(toPlace(getFromStack()) + "\n" + toString(exception));
 155  0
     }
 156  
     
 157  
     
 158  
     private static StackTraceElement getFromStack() {
 159  0
         return new Throwable().getStackTrace()[2]; // 必ず呼び出し元から2階層目でこのメソッドを呼ぶこと
 160  
     }
 161  
     private static String toPlace(StackTraceElement stack) {
 162  0
         return stack.getClassName() + "#" + stack.getMethodName() + "("
 163  0
                 + stack.getFileName() + ":" + stack.getLineNumber() + ")";
 164  
     }
 165  
     private static String toString(Object message) {
 166  
         String log;
 167  0
         if (message instanceof Throwable) {
 168  0
             log = "    " + readStackTrace(new StringBuilder(), (Throwable) message, 1, "jp.co.y_net").toString();
 169  0
         } else if (message == null) {
 170  0
             log = "    " + null;
 171  0
         } else {
 172  0
             log = "    " + message.toString();
 173  
         }
 174  0
         return log;
 175  
     }
 176  
     /**
 177  
      * Exceptionの解析ツール
 178  
      * @param sb
 179  
      * @param throwable
 180  
      * @param filter フィルター (スタックトレースの内、指定された文字列以外は無視する。全て有効とする場合はnullを指定。)
 181  
      */
 182  
     private static StringBuilder readStackTrace(StringBuilder sb, Throwable throwable, int token, String filter) {
 183  0
         if(sb == null) sb = new StringBuilder();
 184  0
         final String LINE_SEP = System.getProperty("line.separator");
 185  
         try {
 186  0
             String spacer = "";
 187  0
             for (int i = 0; i < token; i++) {
 188  0
                 spacer += " ";
 189  
             }
 190  0
             sb.append(spacer + throwable.getClass().getName() + ":" + throwable.getMessage() + LINE_SEP);
 191  0
             StackTraceElement[] se = throwable.getStackTrace();
 192  0
             for (int i = 0; i < se.length; i++) {
 193  0
                 String trace = se[i].toString();
 194  0
                 if(filter == null
 195  0
                         || (filter != null && trace.startsWith(filter))) {
 196  
 
 197  0
                         sb.append(spacer + "    " + trace + LINE_SEP);
 198  
                 }
 199  
             }
 200  0
             if (throwable.getCause() != null) {
 201  
                 /* 再帰呼び出し */
 202  0
                 readStackTrace(sb, throwable.getCause(), token + 1, filter);
 203  
             }
 204  0
         } catch (Exception e) {
 205  
             /* Exception解析でのエラーは無視することで、無限ループを回避 */
 206  0
             e.printStackTrace();
 207  
         }
 208  0
         return sb;
 209  
     }
 210  
 }