Skip to content

Commit 3fa990d

Browse files
committed
Replaced the default environment info and updated memory and thread info for every event
1 parent 0ef14f5 commit 3fa990d

File tree

2 files changed

+251
-256
lines changed

2 files changed

+251
-256
lines changed
Lines changed: 251 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,263 @@
11
using System;
2+
using System.Diagnostics;
3+
using System.Globalization;
4+
using System.Linq;
5+
using System.Net;
6+
#if !PORTABLE && !NETSTANDARD1_2
7+
using System.Net.Sockets;
8+
#endif
9+
using System.Runtime.InteropServices;
10+
using System.Text;
11+
using System.Threading;
12+
using Exceptionless.Logging;
213
using Exceptionless.Models.Data;
314

415
namespace Exceptionless.Services {
516
public class DefaultEnvironmentInfoCollector : IEnvironmentInfoCollector {
617
private static EnvironmentInfo _environmentInfo;
18+
private readonly IExceptionlessLog _log;
19+
20+
public DefaultEnvironmentInfoCollector(IExceptionlessLog log) {
21+
_log = log;
22+
}
723

824
public EnvironmentInfo GetEnvironmentInfo() {
9-
if (_environmentInfo == null)
10-
_environmentInfo = new EnvironmentInfo {
11-
MachineName = Guid.NewGuid().ToString("N"),
12-
};
25+
if (_environmentInfo != null) {
26+
PopulateThreadInfo(_environmentInfo);
27+
PopulateMemoryInfo(_environmentInfo);
28+
return _environmentInfo;
29+
}
30+
31+
var info = new EnvironmentInfo();
32+
PopulateRuntimeInfo(info);
33+
PopulateProcessInfo(info);
34+
PopulateThreadInfo(info);
35+
PopulateMemoryInfo(info);
1336

37+
_environmentInfo = info;
1438
return _environmentInfo;
1539
}
40+
41+
private void PopulateApplicationInfo(EnvironmentInfo info) {
42+
#if NET45 || NETSTANDARD1_5
43+
try {
44+
info.Data.Add("AppDomainName", AppDomain.CurrentDomain.FriendlyName);
45+
} catch (Exception ex) {
46+
_log.FormattedInfo(typeof(EnvironmentInfoCollector), "Unable to get AppDomain friendly name. Error message: {0}", ex.Message);
47+
}
48+
#endif
49+
50+
#if !PORTABLE && !NETSTANDARD1_2
51+
try {
52+
IPHostEntry hostEntry = Dns.GetHostEntryAsync(Dns.GetHostName()).ConfigureAwait(false).GetAwaiter().GetResult();
53+
if (hostEntry != null && hostEntry.AddressList.Any())
54+
info.IpAddress = String.Join(", ", hostEntry.AddressList.Where(x => x.AddressFamily == AddressFamily.InterNetwork).Select(a => a.ToString()).ToArray());
55+
} catch (Exception ex) {
56+
_log.FormattedInfo(typeof(EnvironmentInfoCollector), "Unable to get ip address. Error message: {0}", ex.Message);
57+
}
58+
#endif
59+
}
60+
61+
private void PopulateProcessInfo(EnvironmentInfo info) {
62+
try {
63+
info.ProcessorCount = Environment.ProcessorCount;
64+
} catch (Exception ex) {
65+
_log.FormattedInfo(typeof(EnvironmentInfoCollector), "Unable to get processor count. Error message: {0}", ex.Message);
66+
}
67+
68+
#if !PORTABLE && !NETSTANDARD1_2
69+
try {
70+
Process process = Process.GetCurrentProcess();
71+
info.ProcessName = process.ProcessName;
72+
info.ProcessId = process.Id.ToString(NumberFormatInfo.InvariantInfo);
73+
} catch (Exception ex) {
74+
_log.FormattedInfo(typeof(EnvironmentInfoCollector), "Unable to get process name or id. Error message: {0}", ex.Message);
75+
}
76+
77+
try {
78+
#if NETSTANDARD1_5
79+
info.CommandLine = String.Join(" ", Environment.GetCommandLineArgs());
80+
#elif NET45
81+
info.CommandLine = Environment.CommandLine;
82+
#endif
83+
} catch (Exception ex) {
84+
_log.FormattedInfo(typeof(EnvironmentInfoCollector), "Unable to get command line. Error message: {0}", ex.Message);
85+
}
86+
#endif
87+
}
88+
89+
private void PopulateThreadInfo(EnvironmentInfo info) {
90+
#if !PORTABLE && !NETSTANDARD1_2
91+
try {
92+
info.ThreadId = Thread.CurrentThread.ManagedThreadId.ToString(NumberFormatInfo.InvariantInfo);
93+
} catch (Exception ex) {
94+
_log.FormattedInfo(typeof(EnvironmentInfoCollector), "Unable to get thread id. Error message: {0}", ex.Message);
95+
}
96+
97+
try {
98+
info.ThreadName = Thread.CurrentThread.Name;
99+
} catch (Exception ex) {
100+
_log.FormattedInfo(typeof(EnvironmentInfoCollector), "Unable to get current thread name. Error message: {0}", ex.Message);
101+
}
102+
#endif
103+
}
104+
105+
private void PopulateMemoryInfo(EnvironmentInfo info) {
106+
#if !PORTABLE && !NETSTANDARD1_2
107+
try {
108+
Process process = Process.GetCurrentProcess();
109+
info.ProcessMemorySize = process.PrivateMemorySize64;
110+
} catch (Exception ex) {
111+
_log.FormattedInfo(typeof(EnvironmentInfoCollector), "Unable to get process memory size. Error message: {0}", ex.Message);
112+
}
113+
#endif
114+
115+
#if NET45
116+
try {
117+
if (IsMonoRuntime) {
118+
if (PerformanceCounterCategory.Exists("Mono Memory")) {
119+
var totalPhysicalMemory = new PerformanceCounter("Mono Memory", "Total Physical Memory");
120+
info.TotalPhysicalMemory = Convert.ToInt64(totalPhysicalMemory.RawValue);
121+
122+
var availablePhysicalMemory = new PerformanceCounter("Mono Memory", "Available Physical Memory"); //mono 4.0+
123+
info.AvailablePhysicalMemory = Convert.ToInt64(availablePhysicalMemory.RawValue);
124+
}
125+
} else {
126+
var computerInfo = new Microsoft.VisualBasic.Devices.ComputerInfo();
127+
info.TotalPhysicalMemory = Convert.ToInt64(computerInfo.TotalPhysicalMemory);
128+
info.AvailablePhysicalMemory = Convert.ToInt64(computerInfo.AvailablePhysicalMemory);
129+
}
130+
} catch (Exception ex) {
131+
_log.FormattedInfo(typeof(EnvironmentInfoCollector), "Unable to get physical memory. Error message: {0}", ex.Message);
132+
}
133+
#endif
134+
}
135+
136+
#if NET45
137+
private bool IsMonoRuntime {
138+
get {
139+
try {
140+
return Type.GetType("Mono.Runtime") != null;
141+
} catch (Exception) {
142+
return false;
143+
}
144+
}
145+
}
146+
#endif
147+
148+
private void PopulateRuntimeInfo(EnvironmentInfo info) {
149+
try {
150+
#if NET45 || NETSTANDARD1_5
151+
info.MachineName = Environment.MachineName;
152+
#elif !PORTABLE && !NETSTANDARD1_2
153+
Process process = Process.GetCurrentProcess();
154+
info.MachineName = process.MachineName;
155+
#else
156+
info.MachineName = Guid.NewGuid().ToString("N");
157+
#endif
158+
} catch (Exception ex) {
159+
_log.FormattedInfo(typeof(EnvironmentInfoCollector), "Unable to get machine name. Error message: {0}", ex.Message);
160+
}
161+
162+
#if !PORTABLE && !NETSTANDARD1_2
163+
#if NETSTANDARD
164+
Microsoft.Extensions.PlatformAbstractions.PlatformServices computerInfo = null;
165+
#elif NET45
166+
Microsoft.VisualBasic.Devices.ComputerInfo computerInfo = null;
167+
#endif
168+
169+
try {
170+
#if NETSTANDARD
171+
computerInfo = Microsoft.Extensions.PlatformAbstractions.PlatformServices.Default;
172+
#elif NET45
173+
computerInfo = new Microsoft.VisualBasic.Devices.ComputerInfo();
174+
#endif
175+
} catch (Exception ex) {
176+
_log.FormattedInfo(typeof(EnvironmentInfoCollector), "Unable to get computer info. Error message: {0}", ex.Message);
177+
}
178+
179+
#if NETSTANDARD || NET45
180+
if (computerInfo == null)
181+
return;
182+
#endif
183+
184+
try {
185+
#if NETSTANDARD
186+
info.Data["ApplicationBasePath"] = computerInfo.Application.ApplicationBasePath;
187+
info.Data["ApplicationName"] = computerInfo.Application.ApplicationName;
188+
info.Data["RuntimeFramework"] = computerInfo.Application.RuntimeFramework.FullName;
189+
190+
info.OSName = computerInfo.Runtime.OperatingSystem;
191+
info.OSVersion = computerInfo.Runtime.OperatingSystemVersion;
192+
info.Architecture = computerInfo.Runtime.RuntimeArchitecture;
193+
info.RuntimeVersion = computerInfo.Runtime.RuntimeVersion;
194+
info.Data["RuntimeType"] = computerInfo.Runtime.RuntimeType; // Mono, CLR, CoreCLR
195+
#elif NET45
196+
info.OSName = computerInfo.OSFullName;
197+
info.OSVersion = computerInfo.OSVersion;
198+
info.Architecture = Is64BitOperatingSystem() ? "x64" : "x86";
199+
info.RuntimeVersion = Environment.Version.ToString();
200+
#endif
201+
} catch (Exception ex) {
202+
_log.FormattedInfo(typeof(EnvironmentInfoCollector), "Unable to get populate runtime info. Error message: {0}", ex.Message);
203+
}
204+
#endif
205+
}
206+
207+
#if NET45
208+
private bool Is64BitOperatingSystem() {
209+
if (IntPtr.Size == 8) // 64-bit programs run only on Win64
210+
return true;
211+
212+
try {
213+
// Detect whether the current process is a 32-bit process running on a 64-bit system.
214+
bool is64;
215+
bool methodExist = KernelNativeMethods.MethodExists("kernel32.dll", "IsWow64Process");
216+
217+
return ((methodExist && KernelNativeMethods.IsWow64Process(KernelNativeMethods.GetCurrentProcess(), out is64)) && is64);
218+
} catch (Exception ex) {
219+
_log.FormattedInfo(typeof(EnvironmentInfoCollector), "Unable to get CPU architecture. Error message: {0}", ex.Message);
220+
}
221+
222+
return false;
223+
}
224+
225+
private static class KernelNativeMethods {
226+
#region Kernel32
227+
228+
[DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
229+
public static extern IntPtr GetProcAddress(IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)] string procName);
230+
231+
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
232+
[return: MarshalAs(UnmanagedType.Bool)]
233+
public static extern bool IsWow64Process(IntPtr hProcess, out bool wow64Process);
234+
235+
[DllImport("kernel32.dll")]
236+
public static extern IntPtr GetCurrentProcess();
237+
238+
[DllImport("kernel32.dll")]
239+
public static extern int GetCurrentProcessId();
240+
241+
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
242+
[PreserveSig]
243+
public static extern int GetModuleFileName([In] IntPtr hModule, [Out] StringBuilder lpFilename, [In] [MarshalAs(UnmanagedType.U4)] int nSize);
244+
245+
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
246+
public static extern IntPtr GetModuleHandle(string moduleName);
247+
248+
[DllImport("kernel32.dll")]
249+
public static extern int GetCurrentThreadId();
250+
251+
#endregion
252+
253+
public static bool MethodExists(string moduleName, string methodName) {
254+
IntPtr moduleHandle = GetModuleHandle(moduleName);
255+
if (moduleHandle == IntPtr.Zero)
256+
return false;
257+
258+
return (GetProcAddress(moduleHandle, methodName) != IntPtr.Zero);
259+
}
260+
}
261+
#endif
16262
}
17-
}
263+
}

0 commit comments

Comments
 (0)