Windows 응용 프로그램 이벤트 로그에 쓰기
이 이벤트 로그에 쓰는 방법이 있습니까?
또는 적어도 이벤트 소스를 등록 할 필요가없는 다른 Windows 기본 로그 는 무엇입니까?
예, 찾고있는 이벤트 로그에 쓸 수있는 방법이 있습니다. 새로운 소스를 만들 필요는 없으며, 종종 EventLog의 이름과 이름이 같은 기존 소스를 사용하기 만하면되고 이벤트 로그 응용 프로그램과 같은 일부 경우에는 관리자 권한없이 액세스 할 수 있습니다 *.
* 직접 액세스 할 수없는 다른 경우는 보안 이벤트 로그입니다 (예 : 운영 체제에서만 액세스).
이 코드를 사용하여 이벤트 로그 응용 프로그램에 직접 작성했습니다.
using (EventLog eventLog = new EventLog("Application"))
{
eventLog.Source = "Application";
eventLog.WriteEntry("Log message example", EventLogEntryType.Information, 101, 1);
}
보시다시피 EventLog 소스는 EventLog의 이름과 동일합니다. 그 이유는 Windows 개발자 센터의 이벤트 소스 에서 찾을 수 있습니다 (소스 이름을 나타내는 부분은 굵게 표시).
Eventlog 키의 각 로그에는 이벤트 소스라는 하위 키가 있습니다. 이벤트 소스는 이벤트를 기록하는 소프트웨어의 이름입니다. 응용 프로그램이 큰 경우 종종 응용 프로그램 이름이거나 응용 프로그램 의 하위 구성 요소 이름입니다. 최대 16,384 개의 이벤트 소스를 레지스트리에 추가 할 수 있습니다.
방법 : 응용 프로그램 이벤트 로그에 쓰기 (Visual C #)에 설명 된대로 EventLog 클래스를 사용할 수 있습니다 .
var appLog = new EventLog("Application");
appLog.Source = "MySource";
appLog.WriteEntry("Test log message");
그러나 관리 권한을 사용 하여이 소스 "MySource" 를 구성해야합니다 .
WriteEvent 및 WriteEntry를 사용하여 이벤트를 이벤트 로그에 기록하십시오. 이벤트를 작성하려면 이벤트 소스를 지정해야합니다. 소스로 첫 번째 항목을 작성하기 전에 이벤트 소스를 작성하고 구성해야합니다.
이것은 내가 사용하는 로거 클래스입니다. private Log () 메소드에는 EventLog.WriteEntry()
이벤트 로그에 실제로 쓰는 방법이 있습니다. 이 코드는 모두 여기에 포함되어있어 편리합니다. 로깅 외에도이 클래스는 메시지가 이벤트 로그에 쓰기에 너무 길지 않은지 확인합니다 (메시지를 잘라냅니다). 메시지가 너무 길면 예외가 발생합니다. 발신자는 소스를 지정할 수도 있습니다. 호출자가 그렇지 않으면이 클래스는 소스를 가져옵니다. 도움이 되길 바랍니다.
그건 그렇고, 웹에서 ObjectDumper를 얻을 수 있습니다. 나는 여기에 모든 것을 게시하고 싶지 않았습니다. 나는 여기에서 내 것을 얻었다 :C:\Program Files (x86)\Microsoft Visual Studio 10.0\Samples\1033\CSharpSamples.zip\LinqSamples\ObjectDumper
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Reflection;
using Xanico.Core.Utilities;
namespace Xanico.Core
{
/// <summary>
/// Logging operations
/// </summary>
public static class Logger
{
// Note: The actual limit is higher than this, but different Microsoft operating systems actually have
// different limits. So just use 30,000 to be safe.
private const int MaxEventLogEntryLength = 30000;
/// <summary>
/// Gets or sets the source/caller. When logging, this logger class will attempt to get the
/// name of the executing/entry assembly and use that as the source when writing to a log.
/// In some cases, this class can't get the name of the executing assembly. This only seems
/// to happen though when the caller is in a separate domain created by its caller. So,
/// unless you're in that situation, there is no reason to set this. However, if there is
/// any reason that the source isn't being correctly logged, just set it here when your
/// process starts.
/// </summary>
public static string Source { get; set; }
/// <summary>
/// Logs the message, but only if debug logging is true.
/// </summary>
/// <param name="message">The message.</param>
/// <param name="debugLoggingEnabled">if set to <c>true</c> [debug logging enabled].</param>
/// <param name="source">The name of the app/process calling the logging method. If not provided,
/// an attempt will be made to get the name of the calling process.</param>
public static void LogDebug(string message, bool debugLoggingEnabled, string source = "")
{
if (debugLoggingEnabled == false) { return; }
Log(message, EventLogEntryType.Information, source);
}
/// <summary>
/// Logs the information.
/// </summary>
/// <param name="message">The message.</param>
/// <param name="source">The name of the app/process calling the logging method. If not provided,
/// an attempt will be made to get the name of the calling process.</param>
public static void LogInformation(string message, string source = "")
{
Log(message, EventLogEntryType.Information, source);
}
/// <summary>
/// Logs the warning.
/// </summary>
/// <param name="message">The message.</param>
/// <param name="source">The name of the app/process calling the logging method. If not provided,
/// an attempt will be made to get the name of the calling process.</param>
public static void LogWarning(string message, string source = "")
{
Log(message, EventLogEntryType.Warning, source);
}
/// <summary>
/// Logs the exception.
/// </summary>
/// <param name="ex">The ex.</param>
/// <param name="source">The name of the app/process calling the logging method. If not provided,
/// an attempt will be made to get the name of the calling process.</param>
public static void LogException(Exception ex, string source = "")
{
if (ex == null) { throw new ArgumentNullException("ex"); }
if (Environment.UserInteractive)
{
Console.WriteLine(ex.ToString());
}
Log(ex.ToString(), EventLogEntryType.Error, source);
}
/// <summary>
/// Recursively gets the properties and values of an object and dumps that to the log.
/// </summary>
/// <param name="theObject">The object to log</param>
[SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Xanico.Core.Logger.Log(System.String,System.Diagnostics.EventLogEntryType,System.String)")]
[SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "object")]
public static void LogObjectDump(object theObject, string objectName, string source = "")
{
const int objectDepth = 5;
string objectDump = ObjectDumper.GetObjectDump(theObject, objectDepth);
string prefix = string.Format(CultureInfo.CurrentCulture,
"{0} object dump:{1}",
objectName,
Environment.NewLine);
Log(prefix + objectDump, EventLogEntryType.Warning, source);
}
private static void Log(string message, EventLogEntryType entryType, string source)
{
// Note: I got an error that the security log was inaccessible. To get around it, I ran the app as administrator
// just once, then I could run it from within VS.
if (string.IsNullOrWhiteSpace(source))
{
source = GetSource();
}
string possiblyTruncatedMessage = EnsureLogMessageLimit(message);
EventLog.WriteEntry(source, possiblyTruncatedMessage, entryType);
// If we're running a console app, also write the message to the console window.
if (Environment.UserInteractive)
{
Console.WriteLine(message);
}
}
private static string GetSource()
{
// If the caller has explicitly set a source value, just use it.
if (!string.IsNullOrWhiteSpace(Source)) { return Source; }
try
{
var assembly = Assembly.GetEntryAssembly();
// GetEntryAssembly() can return null when called in the context of a unit test project.
// That can also happen when called from an app hosted in IIS, or even a windows service.
if (assembly == null)
{
assembly = Assembly.GetExecutingAssembly();
}
if (assembly == null)
{
// From http://stackoverflow.com/a/14165787/279516:
assembly = new StackTrace().GetFrames().Last().GetMethod().Module.Assembly;
}
if (assembly == null) { return "Unknown"; }
return assembly.GetName().Name;
}
catch
{
return "Unknown";
}
}
// Ensures that the log message entry text length does not exceed the event log viewer maximum length of 32766 characters.
private static string EnsureLogMessageLimit(string logMessage)
{
if (logMessage.Length > MaxEventLogEntryLength)
{
string truncateWarningText = string.Format(CultureInfo.CurrentCulture, "... | Log Message Truncated [ Limit: {0} ]", MaxEventLogEntryLength);
// Set the message to the max minus enough room to add the truncate warning.
logMessage = logMessage.Substring(0, MaxEventLogEntryLength - truncateWarningText.Length);
logMessage = string.Format(CultureInfo.CurrentCulture, "{0}{1}", logMessage, truncateWarningText);
}
return logMessage;
}
}
}
As stated in MSDN (eg. https://msdn.microsoft.com/en-us/library/system.diagnostics.eventlog(v=vs.110).aspx ), checking an non existing source and creating a source requires admin privilege.
It is however possible to use the source "Application" without. In my test under Windows 2012 Server r2, I however get the following log entry using "Application" source:
The description for Event ID xxxx from source Application cannot be found. Either the component that raises this event is not installed on your local computer or the installation is corrupted. You can install or repair the component on the local computer. If the event originated on another computer, the display information had to be saved with the event. The following information was included with the event: {my event entry message} the message resource is present but the message is not found in the string/message table
I defined the following method to create the source:
private string CreateEventSource(string currentAppName)
{
string eventSource = currentAppName;
bool sourceExists;
try
{
// searching the source throws a security exception ONLY if not exists!
sourceExists = EventLog.SourceExists(eventSource);
if (!sourceExists)
{ // no exception until yet means the user as admin privilege
EventLog.CreateEventSource(eventSource, "Application");
}
}
catch (SecurityException)
{
eventSource = "Application";
}
return eventSource;
}
I am calling it with currentAppName = AppDomain.CurrentDomain.FriendlyName
It might be possible to use the EventLogPermission class instead of this try/catch but not sure we can avoid the catch.
It is also possible to create the source externally, e.g in elevated Powershell:
New-EventLog -LogName Application -Source MyApp
그런 다음 위의 방법에서 'MyApp'을 사용하면 예외가 발생하지 않으며 해당 소스로 EventLog를 만들 수 있습니다.
시험
System.Diagnostics.EventLog appLog = new System.Diagnostics.EventLog();
appLog.Source = "This Application's Name";
appLog.WriteEntry("An entry to the Application event log.");
참고 URL : https://stackoverflow.com/questions/25725151/write-to-windows-application-event-log
'Programming' 카테고리의 다른 글
SVN 업그레이드 작업 사본 (0) | 2020.07.03 |
---|---|
JPA @Column 주석을 참조하여 insertable = false 및 updatable = false에 대해 설명하십시오. (0) | 2020.07.03 |
Eclipse에서 최대 절전 모드 도구를 설치하는 방법은 무엇입니까? (0) | 2020.07.03 |
AngularJS UI 라우터-상태를 다시로드하지 않고 URL 변경 (0) | 2020.07.03 |
Objective-C에서 메소드 오버로드? (0) | 2020.07.03 |