[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 }