New e-d-s backend which indexes all local addressbooks and calendars.
[beagle.git] / Util / Logger.cs
blob21cf4c9f7c6166e89f0df5dfcc4d2540236bbaea
1 //
2 // Logger.cs
3 //
4 // Copyright (C) 2004 Novell, Inc.
5 //
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
15 // The above copyright notice and this permission notice shall be included in all
16 // copies or substantial portions of the Software.
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 // SOFTWARE.
27 using System;
28 using System.Collections;
29 using System.Text;
30 using System.IO;
31 using System.Diagnostics;
33 namespace Beagle.Util {
35 public enum LogLevel {
36 None,
37 Fatal,
38 Error,
39 Warn,
40 Info,
41 Debug
44 public class Logger {
46 private static Hashtable loggers = new Hashtable ();
47 private static LogLevel defaultLevel = LogLevel.Debug; //LogLevel.Info;
48 private static TextWriter defaultWriter = null;
49 private static bool defaultEcho = true; //false;
50 private static string defaultLogName = null;
52 public static Logger Log {
53 get {
54 return Get ("other");
58 public static Logger Get (string logName)
60 if (loggers.ContainsKey (logName)) {
61 return (Logger)loggers[logName];
62 } else {
63 Logger log = new Logger (logName);
64 log.Level = defaultLevel;
65 log.Writer = defaultWriter;
66 log.Echo = defaultEcho;
67 loggers[logName] = log;
68 return log;
72 public static LogLevel DefaultLevel {
73 get { return defaultLevel; }
74 set { defaultLevel = value; }
78 public static TextWriter DefaultWriter {
79 get { return defaultWriter; }
80 set { defaultWriter = value; }
83 public static bool DefaultEcho {
84 get { return defaultEcho; }
85 set { defaultEcho = value; }
88 private static object write_lock = new object ();
90 private bool levelSet = false;
91 private LogLevel level;
92 private TextWriter writer = null;
93 private bool echo = false;
95 private Logger (string name) {
98 public LogLevel Level {
99 get { lock (this) { return (levelSet) ? level : DefaultLevel; } }
100 set { lock (this) { level = value; levelSet = true; } }
103 public TextWriter Writer {
104 get { return writer; }
105 set { writer = value; }
108 public bool Echo {
109 get { return echo; }
110 set { echo = value; }
113 // Multiple logs can be merge-sorted via "sort -m log1 log2 ..."
114 private string GetStamp ()
116 StringBuilder builder = new StringBuilder ();
117 builder.AppendFormat ("{0:yy-MM-dd HH.mm.ss.ff} ", DateTime.Now);
118 builder.AppendFormat ("{0:00000} ", Process.GetCurrentProcess().Id);
119 if (defaultLogName != null) {
120 builder.AppendFormat (defaultLogName);
121 builder.Append (' ');
123 return builder.ToString ();
126 private void WriteLine (string level, string message) {
127 if (Writer != null) {
128 lock (write_lock) {
129 Writer.WriteLine ("{0}{1}: {2}", GetStamp (), level, message);
130 Writer.Flush ();
133 if (Echo)
134 System.Console.WriteLine ("{0}: {1}", level, message);
137 public void Debug (string message, params object [] args)
139 if (IsDebugEnabled) {
140 WriteLine ("DEBUG", String.Format (message, args));
144 public void Debug (Exception e)
146 Debug ("{0}", e);
149 public void Info (string message, params object [] args)
151 if (IsInfoEnabled) {
152 WriteLine ("INFO", String.Format (message, args));
156 public void Info (Exception e)
158 Info ("{0}", e);
161 public void Warn (string message, params object [] args)
163 if (IsWarnEnabled) {
164 WriteLine ("WARN", String.Format (message, args));
168 public void Warn (Exception e)
170 Warn ("{0}", e);
173 public void Error (string message, params object [] args)
175 if (IsErrorEnabled) {
176 WriteLine ("ERROR", String.Format (message, args));
180 public void Error (Exception e)
182 Error ("{0}", e);
185 public void Fatal (string message, params object [] args)
187 if (IsFatalEnabled) {
188 WriteLine ("FATAL", String.Format (message, args));
192 public void Fatal (Exception e)
194 Fatal ("{0}", e);
197 public bool IsDebugEnabled { get { return level >= LogLevel.Debug; } }
198 public bool IsInfoEnabled { get { return level >= LogLevel.Info; } }
199 public bool IsWarnEnabled { get { return level >= LogLevel.Warn; } }
200 public bool IsErrorEnabled { get { return level >= LogLevel.Error;} }
201 public bool IsFatalEnabled { get { return level >= LogLevel.Fatal; } }
203 ////////////////////////////////////////////////////////////////////////////////
205 static private void PruneOldLogs (string path, string instance)
207 DateTime magic_date = DateTime.Now.AddDays (-7);
208 DirectoryInfo dir = new DirectoryInfo (path);
210 foreach (FileInfo file in dir.GetFiles ()) {
211 if (file.Name.StartsWith ("current") || (! file.Name.EndsWith (instance)))
212 continue;
214 int last_dash = file.Name.LastIndexOf ("-");
215 if (last_dash == -1)
216 continue; // skip strange-looking files
218 string date = file.Name.Substring (0, last_dash);
220 try {
221 DateTime log_date;
222 log_date = DateTime.ParseExact (date, "yyyy-MM-dd-HH-mm-ss", null);
223 if (log_date < magic_date)
224 file.Delete ();
225 } catch (Exception e) { }
229 static public void LogToFile (string path, string name, bool foreground_mode)
231 defaultLogName = name;
232 if (defaultLogName.Length > 6)
233 defaultLogName = defaultLogName.Substring (0, 6);
234 else
235 defaultLogName = defaultLogName.PadRight (6);
237 string timestamped_name = String.Format ("{0:yyyy-MM-dd-HH-mm-ss}-{1}", DateTime.Now, name);
238 string log_path = Path.Combine (path, timestamped_name);
239 string log_link = Path.Combine (path, "current-" + name);
241 // Delete old and obsolete log files
242 PruneOldLogs (path, name);
244 // Open the log file and set it as the default
245 // destination for log messages.
246 // Also redirect stdout and stderr to the same file.
247 FileStream log_stream = new FileStream (log_path,
248 FileMode.Append,
249 FileAccess.Write,
250 FileShare.Write);
251 TextWriter log_writer = new StreamWriter (log_stream);
253 File.Delete (log_link);
254 Mono.Posix.Syscall.symlink (log_path, log_link);
256 Logger.DefaultWriter = log_writer;
257 Logger.DefaultEcho = foreground_mode;
259 if (! foreground_mode) {
261 // Redirect stdout and stderr to the logfile
262 Console.SetOut (Logger.DefaultWriter);
263 Console.SetError (Logger.DefaultWriter);
265 // Redirect stdin to /dev/null
266 FileStream dev_null_stream = new FileStream ("/dev/null",
267 FileMode.Open,
268 FileAccess.Read,
269 FileShare.ReadWrite);
270 TextReader dev_null_reader = new StreamReader (dev_null_stream);
271 Console.SetIn (dev_null_reader);
275 ////////////////////////////////////////////////////////////////////////////////
277 static Logger ()
279 // Parse the contents of the BEAGLE_DEBUG environment variable
280 // and adjust the default log levels accordingly.
281 string debug = System.Environment.GetEnvironmentVariable ("BEAGLE_DEBUG");
282 if (debug != null) {
283 string[] debugArgs = debug.Split (',');
284 foreach (string arg in debugArgs) {
285 if (arg.Trim () == "all") {
286 Logger.DefaultLevel = LogLevel.Debug;
290 foreach (string arg_raw in debugArgs) {
291 string arg = arg_raw.Trim ();
293 if (arg.Length == 0 || arg == "all")
294 continue;
296 if (arg[0] == '-') {
297 string name = arg.Substring (1);
298 Logger log = Logger.Get (name);
299 log.Level = LogLevel.Info;
300 } else {
301 Logger log = Logger.Get (arg);
302 log.Level = LogLevel.Debug;