/* * SVN: $Id: Logging.cs 11535 2010-10-07 13:07:34Z dave.nay $ * * Copyright (c) 2008 CIVision, LLC. * 2640 White Oak Circle, Unit A, Aurora, Illinois, 60502, U.S.A. * All rights reserved. * * This software is the confidential and proprietary information of * CIVision, LLC ("Confidential Information"). You shall not * disclose such Confidential Information and shall use it only in * accordance with the terms of the license agreement you entered into * with CIVision, LLC. */ using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Runtime.InteropServices; using log4net.Core; using log4net.Layout.Pattern; using log4net.Util; namespace CIVision { internal class QpcPatternConverter : PatternLayoutConverter, IOptionHandler { private bool _alignDecimalPoint = true; private bool _difference; private ulong _firstQpcValue; private double _frequency = 1; private ulong _lastQpcValue; private bool _normalize = true; private int _precision = 6; protected bool AlignDecimalPoint { get { return _alignDecimalPoint; } set { _alignDecimalPoint = value; } } protected int Precision { get { return _precision; } set { _precision = value; } } protected bool Normalize { get { return _normalize; } set { _normalize = value; } } protected bool Difference { get { return _difference; } set { _difference = value; } } [DllImport("kernel32.dll")] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool QueryPerformanceCounter(out ulong lpPerformanceCount); [DllImport("kernel32.dll")] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool QueryPerformanceFrequency(out ulong lpPerformanceFrequency); protected override void Convert(TextWriter writer, LoggingEvent loggingEvent) { try { ulong qpcValue; if (!QueryPerformanceCounter(out qpcValue)) { return; } ulong v = qpcValue; if (Difference) { qpcValue -= _lastQpcValue; } else if (Normalize) { qpcValue -= _firstQpcValue; } _lastQpcValue = v; double val = Math.Round(qpcValue/_frequency, Precision); string formatString = String.Format("F{0}", Precision); string stringValue = val.ToString(formatString, CultureInfo.InvariantCulture); if (AlignDecimalPoint) { int p = stringValue.IndexOf('.'); if (p == -1) { stringValue += "." + new string('0', Precision); } else { stringValue += new string('0', Precision - (stringValue.Length - 1 - p)); } } writer.Write(stringValue); } catch (Exception ex) { LogLog.Error("DatePatternConverter: Error occurred while converting qpc.", ex); } } #region Implementation of IOptionHandler public void ActivateOptions() { if (!String.IsNullOrEmpty(Option)) { CIVDictionary options = new CIVDictionary(); if(Option.Contains(":")) { string[] pairs = Option.Split(':'); foreach (string pair in pairs) { if (pair.Contains("=")) { string[] keyValuePair = pair.Split('='); options.Add(keyValuePair[0].Trim(), keyValuePair[1].Trim()); } } } else if(Option.Contains("=")) { string[] keyValuePair = Option.Split('='); options.Add(keyValuePair[0].Trim(), keyValuePair[1].Trim()); } foreach (KeyValuePair pair in options) { switch (pair.Key.ToUpperInvariant()) { case "NORMALIZE": try { Normalize = System.Convert.ToBoolean(pair.Value); } catch (Exception e) { LogLog.Error("QpcPatternConverter: Could not convert parameter Normalize to boolean", e); } break; case "DIFFERENCE": try { Difference = System.Convert.ToBoolean(pair.Value); } catch (Exception e) { LogLog.Error("QpcPatternConverter: Could not convert parameter Difference to boolean", e); } break; case "ALIGNDECIMALPOINT": try { AlignDecimalPoint = System.Convert.ToBoolean(pair.Value); } catch (Exception e) { LogLog.Error("QpcPatternConverter: Could not convert parameter AlignDecimalPoint to boolean", e); } break; case "PRECISION": try { Precision = System.Convert.ToInt32(pair.Value); } catch (Exception e) { LogLog.Error("QpcPatternConverter: Could not convert parameter Precision to int32", e); } break; default: break; } } } ulong performanceFrequency; if (!QueryPerformanceFrequency(out performanceFrequency)) { LogLog.Error("QpcPatternConverter: Cannot determine high-performance counter frequency."); } ulong qpcValue; if (!QueryPerformanceCounter(out qpcValue)) { LogLog.Error("Cannot determine high-performance counter value."); } _frequency = performanceFrequency; _firstQpcValue = qpcValue; _lastQpcValue = qpcValue; } #endregion } }