mirror of
https://github.com/xcp-ng/xenadmin.git
synced 2024-12-18 06:30:08 +01:00
bd36a85bff
Signed-off-by: Mihaela Stoica <mihaela.stoica@citrix.com>
453 lines
18 KiB
C#
453 lines
18 KiB
C#
/* Copyright (c) Citrix Systems Inc.
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms,
|
|
* with or without modification, are permitted provided
|
|
* that the following conditions are met:
|
|
*
|
|
* * Redistributions of source code must retain the above
|
|
* copyright notice, this list of conditions and the
|
|
* following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above
|
|
* copyright notice, this list of conditions and the
|
|
* following disclaimer in the documentation and/or other
|
|
* materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*/
|
|
|
|
// ============================================================================
|
|
// Description: Utilitiy functions built on top of libxen for use in all
|
|
// providers.
|
|
// ============================================================================
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Reflection;
|
|
using System.Reflection.Emit;
|
|
using System.Security.Permissions;
|
|
using System.Text;
|
|
using System.Threading;
|
|
|
|
namespace XenOvf.Utilities
|
|
{
|
|
[Flags]
|
|
public enum EnumLogLevel { Off = 0, Audit = 1, Error = 2, Warning = 4, Info = 8, Trace = 16, Debug = 32 };
|
|
[Flags]
|
|
public enum EnumLogType { Off = 0, Audit = 1, Console = 2, File = 4, Event = 8, Exception = 16 };
|
|
public sealed class Log
|
|
{
|
|
private static FileStream fs;
|
|
private static string logpath = null;
|
|
private static string logfile = null;
|
|
private static object lockfile = new object();
|
|
private static object lockevent = new object();
|
|
private static object lockexcept = new object();
|
|
private static EnumLogLevel defaultLogLevel = (EnumLogLevel.Audit | EnumLogLevel.Error | EnumLogLevel.Warning);
|
|
private static EnumLogType defaultLogType = (EnumLogType.Audit | EnumLogType.Console | EnumLogType.File);
|
|
private static bool isconfigured = false;
|
|
private static EnumLogLevel curLevel = defaultLogLevel;
|
|
private static EnumLogType logType = defaultLogType;
|
|
|
|
private Log() { }
|
|
|
|
[SecurityPermission(SecurityAction.LinkDemand)]
|
|
public static string GetLogPath()
|
|
{
|
|
string path = null;
|
|
if (Properties.Settings.Default.LogPath.ToLower().StartsWith("installlocation"))
|
|
{
|
|
path = Path.GetDirectoryName(Assembly.GetCallingAssembly().Location);
|
|
}
|
|
else if (Properties.Settings.Default.LogPath.ToLower().StartsWith("applicationdata"))
|
|
{
|
|
path = Path.Combine(System.Environment.GetEnvironmentVariable("APPDATA"), Properties.Settings.Default.LogSubPath);
|
|
}
|
|
else if (Properties.Settings.Default.LogPath.ToLower().StartsWith("programdata"))
|
|
{
|
|
path = Path.Combine(System.Environment.GetEnvironmentVariable("ProgramData"), Properties.Settings.Default.LogSubPath);
|
|
}
|
|
else
|
|
{
|
|
path = Properties.Settings.Default.LogPath;
|
|
}
|
|
return path;
|
|
}
|
|
|
|
[SecurityPermission(SecurityAction.LinkDemand)]
|
|
public static string GetLogFileName()
|
|
{
|
|
return logfile;
|
|
}
|
|
|
|
[SecurityPermission(SecurityAction.LinkDemand)]
|
|
public static void Trace(string format, params object[] args)
|
|
{
|
|
Write(EnumLogLevel.Trace, format, args);
|
|
}
|
|
|
|
[SecurityPermission(SecurityAction.LinkDemand)]
|
|
public static void Debug(string format, params object[] args)
|
|
{
|
|
Write(EnumLogLevel.Debug, format, args);
|
|
}
|
|
|
|
[SecurityPermission(SecurityAction.LinkDemand)]
|
|
public static void Info(string format, params object[] args)
|
|
{
|
|
Write(EnumLogLevel.Info, format, args);
|
|
}
|
|
|
|
[SecurityPermission(SecurityAction.LinkDemand)]
|
|
public static void Warning(string format, params object[] args)
|
|
{
|
|
Write(EnumLogLevel.Warning, format, args);
|
|
}
|
|
|
|
[SecurityPermission(SecurityAction.LinkDemand)]
|
|
public static void Error(string format, params object[] args)
|
|
{
|
|
Write(EnumLogLevel.Error, format, args);
|
|
}
|
|
|
|
[SecurityPermission(SecurityAction.LinkDemand)]
|
|
public static void Audit(string format, params object[] args)
|
|
{
|
|
Write(EnumLogLevel.Audit, format, args);
|
|
}
|
|
|
|
[SecurityPermission(SecurityAction.LinkDemand)]
|
|
public static void Bytes(byte[] bytes)
|
|
{
|
|
EnumLogLevel curLevel = (EnumLogLevel)Enum.Parse(typeof(EnumLogLevel), Properties.Settings.Default.LogLevel, true);
|
|
EnumLogType logType = (EnumLogType)Enum.Parse(typeof(EnumLogType), Properties.Settings.Default.LogType, true);
|
|
|
|
#region LOG TO CONSOLE
|
|
if (logType >= EnumLogType.Console)
|
|
{
|
|
Console.WriteLine(Encoding.ASCII.GetString(bytes));
|
|
}
|
|
#endregion
|
|
|
|
#region LOG TO FILE
|
|
if (logType >= EnumLogType.File)
|
|
{
|
|
lock (lockfile)
|
|
{
|
|
if (fs == null)
|
|
{
|
|
try
|
|
{
|
|
fs = new FileStream(logfile, FileMode.Create, FileAccess.Write, FileShare.Read);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new Exception("Cannot open Repository, try running as Administrator or change location of Log", ex);
|
|
}
|
|
}
|
|
if (fs != null)
|
|
{
|
|
try
|
|
{
|
|
StreamWriter sw = new StreamWriter(fs);
|
|
sw.WriteLine(Encoding.ASCII.GetString(bytes));
|
|
sw.Flush();
|
|
}
|
|
catch
|
|
{
|
|
// do nothing
|
|
}
|
|
finally
|
|
{
|
|
// do nothing
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
}
|
|
|
|
[SecurityPermission(SecurityAction.LinkDemand)]
|
|
private static void Write(EnumLogLevel level, string format, params object[] args)
|
|
{
|
|
string forwardstatus = null;
|
|
string resetloglevel = null;
|
|
string resetlogtype = null;
|
|
if (Properties.Settings.Default.LogForwarding.Length > 0 &&
|
|
!Properties.Settings.Default.LogForwarding.ToLower().StartsWith("no") &&
|
|
!Properties.Settings.Default.LogForwarding.ToLower().StartsWith("off"))
|
|
{
|
|
try
|
|
{
|
|
Forward(Properties.Settings.Default.LogForwarding, level, format, args);
|
|
return;
|
|
}
|
|
catch
|
|
{
|
|
forwardstatus = "FWD: ";
|
|
}
|
|
}
|
|
|
|
if (logpath == null || logfile == null)
|
|
{
|
|
logpath = GetLogPath();
|
|
logfile = Path.Combine(logpath, Properties.Settings.Default.LogFile);
|
|
}
|
|
|
|
#region CONFIGURE TYPE AND LEVEL
|
|
if (!isconfigured)
|
|
{
|
|
if (Properties.Settings.Default.LogLevel.Length > 0)
|
|
{
|
|
try
|
|
{
|
|
curLevel = (EnumLogLevel)Enum.Parse(typeof(EnumLogLevel), Properties.Settings.Default.LogLevel, true);
|
|
}
|
|
catch
|
|
{
|
|
curLevel = defaultLogLevel;
|
|
resetloglevel = "--- Failure in determining configured log level, reset to: Audit, Error, Warning";
|
|
}
|
|
|
|
}
|
|
|
|
if (Properties.Settings.Default.LogType.Length > 0)
|
|
{
|
|
try
|
|
{
|
|
logType = (EnumLogType)Enum.Parse(typeof(EnumLogType), Properties.Settings.Default.LogType, true);
|
|
}
|
|
catch
|
|
{
|
|
logType = defaultLogType;
|
|
resetlogtype = "--- Failure in determining configure log type, reset to: Audit, Console, File";
|
|
}
|
|
}
|
|
|
|
if ((curLevel & EnumLogLevel.Audit) != EnumLogLevel.Audit)
|
|
{
|
|
curLevel |= EnumLogLevel.Audit;
|
|
}
|
|
|
|
if ((logType & EnumLogType.Audit) != EnumLogType.Audit)
|
|
{
|
|
logType |= EnumLogType.Audit;
|
|
}
|
|
isconfigured = true;
|
|
}
|
|
#endregion
|
|
|
|
string data = string.Format(format, args);
|
|
string message = null;
|
|
if (level == EnumLogLevel.Audit)
|
|
{
|
|
message = string.Format("{0}:{1}.{2}.{3}.{4}.{5}.{6},{7}:[{8}] {9}",
|
|
level,
|
|
DateTime.Now.Year,
|
|
DateTime.Now.Month,
|
|
DateTime.Now.Day,
|
|
DateTime.Now.Hour,
|
|
DateTime.Now.Minute,
|
|
DateTime.Now.Second,
|
|
DateTime.Now.Millisecond,
|
|
System.Security.Principal.WindowsIdentity.GetCurrent().Name,
|
|
data
|
|
);
|
|
|
|
}
|
|
else
|
|
{
|
|
if (Properties.Settings.Default.LogFormat.ToLower().Equals("plain"))
|
|
{
|
|
message = data;
|
|
}
|
|
else
|
|
{
|
|
message = string.Format("{0}:{1}.{2}.{3}.{4}.{5}.{6},{7}: {8}",
|
|
level,
|
|
DateTime.Now.Year,
|
|
DateTime.Now.Month,
|
|
DateTime.Now.Day,
|
|
DateTime.Now.Hour,
|
|
DateTime.Now.Minute,
|
|
DateTime.Now.Second,
|
|
DateTime.Now.Millisecond,
|
|
data
|
|
);
|
|
}
|
|
}
|
|
|
|
if (forwardstatus != null)
|
|
{
|
|
message = forwardstatus + message;
|
|
}
|
|
|
|
if (curLevel >= level && curLevel != EnumLogLevel.Off && logType != EnumLogType.Off)
|
|
{
|
|
|
|
#region LOG TO CONSOLE
|
|
if ((logType & EnumLogType.Console) == EnumLogType.Console)
|
|
{
|
|
if (resetloglevel != null)
|
|
{
|
|
Console.WriteLine(resetloglevel);
|
|
}
|
|
if (resetlogtype != null)
|
|
{
|
|
Console.WriteLine(resetlogtype);
|
|
}
|
|
Console.WriteLine(message);
|
|
}
|
|
#endregion
|
|
|
|
#region LOG TO FILE
|
|
if ((logType & EnumLogType.File) == EnumLogType.File)
|
|
{
|
|
lock (lockfile)
|
|
{
|
|
if (fs == null)
|
|
{
|
|
try
|
|
{
|
|
fs = new FileStream(logfile, FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new Exception("Cannot open log file, try running as Administrator or change location of Log", ex);
|
|
}
|
|
}
|
|
if (fs != null)
|
|
{
|
|
try
|
|
{
|
|
StreamWriter sw = new StreamWriter(fs);
|
|
if (resetloglevel != null) { sw.WriteLine(resetloglevel); }
|
|
if (resetlogtype != null) { sw.WriteLine(resetlogtype); }
|
|
sw.WriteLine(message);
|
|
sw.Flush();
|
|
sw.Close();
|
|
}
|
|
catch
|
|
{
|
|
// do nothing
|
|
}
|
|
finally
|
|
{
|
|
if (fs != null) fs.Close();
|
|
fs = null;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region LOG TO EVENT
|
|
if ((logType & EnumLogType.Event) == EnumLogType.Event)
|
|
{
|
|
lock (lockevent)
|
|
{
|
|
if (!EventLog.SourceExists(Properties.Settings.Default.LogSource))
|
|
{
|
|
EventLog.CreateEventSource(Properties.Settings.Default.LogSource, "Application");
|
|
}
|
|
EventLogEntryType logtype = EventLogEntryType.Information;
|
|
switch(level)
|
|
{
|
|
case EnumLogLevel.Audit: { logtype = EventLogEntryType.SuccessAudit; break; }
|
|
case EnumLogLevel.Debug: { break; }
|
|
case EnumLogLevel.Error: { logtype = EventLogEntryType.Error; break; }
|
|
case EnumLogLevel.Info: { logtype = EventLogEntryType.Information; break; }
|
|
case EnumLogLevel.Warning: { break; }
|
|
case EnumLogLevel.Trace: { break; }
|
|
case EnumLogLevel.Off: { break; }
|
|
default: { break; }
|
|
}
|
|
EventLog.WriteEntry(Properties.Settings.Default.LogSource, message, logtype);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region LOG TO EXCEPTION
|
|
if ((logType & EnumLogType.Exception) == EnumLogType.Exception)
|
|
{
|
|
lock (lockexcept)
|
|
{
|
|
throw new Exception(message);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region LOG IN DebugView
|
|
if ((curLevel & EnumLogLevel.Debug) == EnumLogLevel.Debug)
|
|
{
|
|
if (resetloglevel != null) { System.Diagnostics.Debug.WriteLine(resetloglevel); }
|
|
if (resetlogtype != null) { System.Diagnostics.Debug.WriteLine(resetlogtype); }
|
|
System.Diagnostics.Debug.WriteLine(message);
|
|
}
|
|
#endregion
|
|
|
|
#region LOG IN TraceView
|
|
if ((curLevel & EnumLogLevel.Trace) == EnumLogLevel.Trace)
|
|
{
|
|
if (resetloglevel != null) { System.Diagnostics.Debug.WriteLine(resetloglevel); }
|
|
if (resetlogtype != null) { System.Diagnostics.Debug.WriteLine(resetlogtype); }
|
|
System.Diagnostics.Trace.WriteLine(message);
|
|
}
|
|
#endregion
|
|
}
|
|
|
|
resetloglevel = null;
|
|
resetlogtype = null;
|
|
}
|
|
|
|
private static void Forward(string AssemblyClassName, EnumLogLevel level, string format, params object[] args)
|
|
{
|
|
|
|
string[] _assemblyinfo = AssemblyClassName.Split(new char[] { ',' });
|
|
|
|
try
|
|
{
|
|
Assembly logassembly = null;
|
|
try
|
|
{
|
|
logassembly = Assembly.GetAssembly(Type.GetType(_assemblyinfo[1]));
|
|
}
|
|
catch { }
|
|
if (logassembly == null)
|
|
{
|
|
string asspath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), _assemblyinfo[0]);
|
|
logassembly = Assembly.LoadFrom(asspath);
|
|
}
|
|
Type LogClassType = logassembly.GetType(_assemblyinfo[1]);
|
|
MethodInfo mi = LogClassType.GetMethod(level.ToString());
|
|
List<object> newargs = new List<object>();
|
|
newargs.Add(format);
|
|
newargs.Add(args);
|
|
|
|
mi.Invoke(null, newargs.ToArray());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw ex;
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|