[WorldWindラーニング]13.ログクラスログ

38688 ワード

直接多重化可能.
  1 using System;

  2 using System.IO;

  3 using System.Diagnostics;

  4 using System.Windows.Forms;

  5 

  6 namespace Utility

  7 {

  8     public class LogEventArgs : EventArgs

  9     {

 10         public int level;

 11         public string category;

 12         public string message;

 13 

 14         public LogEventArgs(int _l, string _c, string _m)

 15         {

 16             level = _l;

 17             category = _c;

 18             message = _m;

 19         }

 20     }

 21     /// <summary>

 22     /// Debug log functionality

 23     /// </summary>

 24     public sealed class Log

 25     {

 26         static StreamWriter logWriter;

 27         static string logPath;

 28         static string logFilePath;

 29 

 30         // a few standard values to facilitate logging

 31         public struct Levels

 32         {

 33             public static readonly int Error = 0;

 34             public static readonly int Warning = 2;

 35             public static readonly int Debug = 5;

 36             public static readonly int Verbose = 7;

 37         };

 38         public static int Level;

 39 

 40         /// <summary>

 41         /// Static class (Only static members)

 42         /// </summary>

 43         private Log()

 44         {}

 45 

 46         static Log()

 47         {

 48             try

 49             {

 50                 // start with a reasonable log level.

 51 #if DEBUG

 52                 Level = 6;

 53 #else

 54                 Level = 4;

 55 #endif

 56                 logPath = DefaultSettingsDirectory();

 57                 Directory.CreateDirectory(logPath);

 58 

 59                 // TODO: do not hardcode logfile name?

 60                 logFilePath = Path.Combine( logPath, "WorldWind.log" );

 61 

 62                 logWriter = new StreamWriter(logFilePath, true);

 63                 logWriter.AutoFlush = true;

 64             }

 65             catch (Exception caught)

 66             {

 67                 throw new System.ApplicationException(String.Format("Unexpected logfile error: {0}", logFilePath), caught);

 68             }

 69         }

 70 

 71         // Return the full default directory path to be used for storing settings files,

 72         // which is also where logfiles will be stored.

 73         public static string DefaultSettingsDirectory() 

 74         {

 75             // Example for Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData):

 76             // @"C:\Documents and Settings\<user>\Application Data"

 77             return Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + DefaultSettingsDirectorySuffix();

 78         }

 79 

 80         // Return the program-specifc part of the full default directory path to be used

 81         // for storing settings files, which is also where logfiles will be stored.

 82         public static string DefaultSettingsDirectorySuffix() 

 83         {

 84             // Application.ProductName is set by AssemblyProduct in \WorldWind\AssembyInfo.cs

 85             Version ver = new Version(Application.ProductVersion);

 86             return string.Format(@"\{0}\{1}\{2}.{3}.{4}.{5}", Application.CompanyName, Application.ProductName, ver.Major, ver.Minor, ver.Build, ver.Revision);

 87         }

 88 

 89         public static void Write(string category, string message)

 90         {

 91             Write(Levels.Error, category, message);

 92         }

 93 

 94         public static void Write(string message)

 95         {

 96             Write(Levels.Error, message);

 97         }

 98 

 99         /// <summary>

100         /// Logs a message to the system log. All messages trigger LogEvents, but only messages with level <= Log.Level are recorded to the log file.

101         /// </summary>

102         /// <param name="level">Log level. 0 (highest) .. 9 (lowest). See Log.Level for filtering</param>

103         /// <param name="category">1 to 4 character long tag for categorizing the log entries.

104         /// If the category is longer than 4 characters it will be clipped.</param>

105         /// <param name="message">The actual log messages to be written.</param>

106         public static void Write(int level, string category, string message)

107         {

108             if (level <= Log.Level)

109             {

110                 try

111                 {

112                     lock (logWriter)

113                     {

114                         string logLine = string.Format("{0} {1} {2} {3}",

115                             DateTime.Now.ToString("u"),

116                             level,

117                             category.PadRight(4, ' ').Substring(0, 4),

118                             message);

119 

120 #if DEBUG

121                         System.Diagnostics.Debug.WriteLine(

122                             string.Format("World Wind"+

123                             //".{0} [{1}]"+

124                             ": {2} {3} {4}", 

125                                 System.Threading.Thread.CurrentThread.Name,

126                                 System.Threading.Thread.CurrentThread.ManagedThreadId,

127                                 level,

128                                 category.PadRight(4, ' ').Substring(0, 4),

129                                 message));

130 #endif

131                         logWriter.WriteLine(logLine);

132                     }

133                 }

134                 catch (Exception caught)

135                 {

136                     throw new System.ApplicationException(String.Format("Unexpected logging error on write(1)"), caught);

137                 }

138             }

139         }

140 

141         /// <summary>

142         /// Logs a message to the system log only in debug builds.

143         /// </summary>

144         /// <param name="category">1 to 4 character long tag for categorizing the log entries.

145         /// If the category is longer than 4 characters it will be clipped.</param>

146         /// <param name="message">The actual log messages to be written.</param>

147         [Conditional("DEBUG")]

148         public static void DebugWrite( string category, string message )

149         {

150             Debug.Write( category, message );

151         }

152 

153         /// <summary>

154         /// Logs a message to the system log

155         /// </summary>

156         public static void Write(int level, string message)

157         {

158             Write(level, "", message);

159         }

160 

161         /// <summary>

162         /// Logs a message to the system log only in debug builds.

163         /// </summary>

164         [Conditional("DEBUG")]

165         public static void DebugWrite( int level, string message )

166         {

167             Write(level, "", message);

168         }

169 

170         /// <summary>

171         /// Writes a log of an exception.

172         /// </summary>

173         /// <param name="caught"></param>

174         public static void Write( Exception caught )

175         {

176             try

177             {

178                 if (caught is System.Threading.ThreadAbortException)

179                     return;

180 

181                 lock (logWriter)

182                 {

183                     string functionName = "Unknown";

184                     string[] stacktrace = null;

185                     if (caught.StackTrace != null)

186                     {

187                         stacktrace = caught.StackTrace.Split('
'); 188 string firstStackTraceLine = stacktrace[0]; 189 functionName = firstStackTraceLine.Trim().Split(" (".ToCharArray())[1]; 190 } 191 string logFileName = string.Format("DEBUG_{0}.txt", DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-ffff")); 192 string logFullPath = Path.Combine(logPath, logFileName); 193 using (StreamWriter sw = new StreamWriter(logFullPath, false)) 194 { 195 sw.WriteLine(caught.ToString()); 196 } 197 198 Write(Log.Levels.Error, "caught exception: "); 199 Write(Log.Levels.Error, caught.ToString()); 200 foreach (string line in stacktrace) 201 Write(Log.Levels.Debug, line); 202 } 203 } 204 catch (Exception caught2) 205 { 206 throw new System.ApplicationException(String.Format("{0}
Unexpected logging error on write(2)
", caught.Message), caught2); 207 } 208 } 209 210 /// <summary> 211 /// Writes a debug log of an exception. 212 /// Only executed in debug builds. 213 /// </summary> 214 [Conditional("DEBUG")] 215 public static void DebugWrite( Exception caught ) 216 { 217 try 218 { 219 if (caught is System.Threading.ThreadAbortException) 220 return; 221 222 string functionName = "Unknown"; 223 if(caught.StackTrace != null) 224 { 225 string firstStackTraceLine = caught.StackTrace.Split('
')[0]; 226 functionName = firstStackTraceLine.Trim().Split(" (".ToCharArray())[1]; 227 } 228 string logFileName = string.Format("DEBUG_{0}.txt", DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss") ); 229 string logFullPath = Path.Combine(logPath, logFileName); 230 using (StreamWriter sw = new StreamWriter(logFullPath, false)) 231 { 232 sw.WriteLine(caught.ToString()); 233 } 234 } 235 catch (Exception caught2) 236 { 237 throw new System.ApplicationException(String.Format("{0}
Unexpected logging error on write(3)
", caught.Message), caught2); 238 } 239 } 240 } 241 }