kopano-ol-extension/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/DebugSupport/DebugInfo.cs

279 lines
8.8 KiB
C#

/// Copyright 2016 Kopano b.v.
///
/// This program is free software: you can redistribute it and/or modify
/// it under the terms of the GNU Affero General Public License, version 3,
/// as published by the Free Software Foundation.
///
/// This program is distributed in the hope that it will be useful,
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
/// GNU Affero General Public License for more details.
///
/// You should have received a copy of the GNU Affero General Public License
/// along with this program.If not, see<http://www.gnu.org/licenses/>.
///
/// Consult LICENSE file for details
using Acacia.Utils;
using Acacia.ZPush;
using Microsoft.Office.Core;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Acacia.Features.DebugSupport
{
public enum DebugCategory
{
Version,
Memory,
Wrappers,
Misc,
System,
Accounts,
Features,
AddIns
}
public class DebugCategoryAttribute : CategoryAttribute
{
// Add tabs; these are not printed, but are used for the sorting
public DebugCategoryAttribute(DebugCategory order)
:
base(order.ToString().PadLeft(typeof(DebugCategory).GetEnumNames().Length - (int)order + order.ToString().Length, '\t'))
{
}
}
public class DebugInfoConverter : ExpandableObjectConverter
{
private class CustomPropertyDescriptor<TProperty, TComponent> : PropertyDescriptor
{
private readonly TProperty value;
public CustomPropertyDescriptor(string propertyName, DebugCategory category, TProperty value)
: base(propertyName, new Attribute[] { new DebugCategoryAttribute(category) })
{
this.value = value;
}
public override bool CanResetValue(object component) { return false; }
public override Type ComponentType { get { return typeof(TComponent); } }
public override object GetValue(object component) { return value; }
public override bool IsReadOnly { get { return true; } }
public override Type PropertyType { get { return typeof(TProperty); } }
public override void ResetValue(object component) { SetValue(component, null); }
public override void SetValue(object component, object value) { }
public override bool ShouldSerializeValue(object component) { return false; }
}
public override bool GetPropertiesSupported(ITypeDescriptorContext context)
{
return true;
}
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
{
PropertyDescriptorCollection properties = new PropertyDescriptorCollection(base.GetProperties(context, value, attributes).Cast<PropertyDescriptor>().ToArray());
DebugInfo info = value as DebugInfo;
if (info != null)
{
// Add accounts
foreach (ZPushAccount account in ThisAddIn.Instance.Watcher.Accounts.GetAccounts())
{
PropertyDescriptor p = new CustomPropertyDescriptor<ZPushAccount, DebugInfo>(account.DisplayName, DebugCategory.Accounts, account);
properties.Add(p);
}
// Add Features
foreach (Feature feature in ThisAddIn.Instance.Features)
{
PropertyDescriptor p = new CustomPropertyDescriptor<Feature, DebugInfo>(feature.Name, DebugCategory.Features, feature);
properties.Add(p);
}
// Add Add-ins
foreach (COMAddIn addin in ThisAddIn.Instance.Application.COMAddIns)
{
PropertyDescriptor p = new CustomPropertyDescriptor<string, DebugInfo>(addin.ProgId, DebugCategory.AddIns, addin.Description);
properties.Add(p);
}
}
return properties;
}
}
[TypeConverter(typeof(DebugInfoConverter))]
class DebugInfo
{
#region Version
[DebugCategory(DebugCategory.Version)]
public string Version { get { return BuildVersions.VERSION; } }
[DebugCategory(DebugCategory.Version)]
public string Revision { get { return BuildVersions.REVISION; } }
[DebugCategory(DebugCategory.Version)]
public string BuildDate { get { return LibUtils.BuildTime.ToString(); } }
#endregion
#region Memory
[DebugCategory(DebugCategory.Memory)]
public string TotalMemory { get { return MemoryToString(GC.GetTotalMemory(false)); } }
#endregion
#region Wrappers
[DebugCategory(DebugCategory.Wrappers)]
public long ActiveWrappers { get { return Statistics.CreatedWrappers - Statistics.DeletedWrappers; } }
[DebugCategory(DebugCategory.Wrappers)]
public long CreatedWrappers { get { return Statistics.CreatedWrappers; } }
[DebugCategory(DebugCategory.Wrappers)]
public long DeletedWrappers { get { return Statistics.DeletedWrappers; } }
[DebugCategory(DebugCategory.Wrappers)]
public long DisposedWrappers { get { return Statistics.DisposedWrappers; } }
[DebugCategory(DebugCategory.Wrappers)]
public long UndisposedWrappers { get { return Statistics.DeletedWrappers - Statistics.DisposedWrappers; } }
#endregion
#region Misc
[DebugCategory(DebugCategory.Misc)]
public string StartupTime { get { return TimeToString(Statistics.StartupTime); } }
[DebugCategory(DebugCategory.Misc)]
public LogLevel LogLevel
{
get { return Logger.Instance.MinLevel; }
set
{
Logger.Instance.SetLevel(value);
}
}
[DebugCategory(DebugCategory.Misc)]
public string Threading
{
get { return Tasks.Executor.Name; }
}
[DebugCategory(DebugCategory.Misc)]
public bool ZPushSync
{
get { return ThisAddIn.Instance.Watcher.Sync.Enabled; }
}
[DebugCategory(DebugCategory.Misc)]
public TimeSpan ZPushSyncPeriod
{
get { return ThisAddIn.Instance.Watcher.Sync.Period; }
}
[DebugCategory(DebugCategory.Misc)]
public string Build
{
get
{
#if DEBUG
return "Debug";
#else
return "Release";
#endif
}
}
#endregion
#region System
[DebugCategory(DebugCategory.System)]
public string Locale
{
get
{
return CultureInfo.CurrentUICulture.DisplayName;
}
}
[DebugCategory(DebugCategory.System)]
public string WindowsVersion
{
get
{
return Environment.OSVersion.Version.ToString();
}
}
[DebugCategory(DebugCategory.System)]
public string Architecture
{
get
{
return Environment.Is64BitOperatingSystem ? "64 bit" : "32 bit";
}
}
#endregion
#region Outlook
[DebugCategory(DebugCategory.System)]
public string OutlookVersion
{
get
{
return ThisAddIn.Instance.Application.Version;
}
}
[DebugCategory(DebugCategory.System)]
public string OutlookArchitecture
{
get
{
return Environment.Is64BitProcess ? "64 bit" : "32 bit";
}
}
#endregion
#region Helpers
private string TimeToString(Stopwatch time)
{
return time.ElapsedMilliseconds.ToString("#### ms");
}
private static readonly string[] SizeSuffixes = { "bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
private string MemoryToString(long value)
{
if (value < 0) { return "-" + MemoryToString(-value); }
int i = 0;
decimal dValue = (decimal)value;
while (Math.Round(dValue / 1024) >= 1)
{
dValue /= 1024;
i++;
}
return string.Format("{0:n1} {1}", dValue, SizeSuffixes[i]);
}
#endregion
}
}