##### 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.0;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

     }