이 이벤트 로그에 쓰는 방법이 있습니까?
또는 적어도 이벤트 소스를 등록 할 필요가없는 다른 Windows 기본 로그 는 무엇입니까?
ServiceBase.EventLog
. 소스의 기본 이름은 ServiceName입니다.
이 이벤트 로그에 쓰는 방법이 있습니까?
또는 적어도 이벤트 소스를 등록 할 필요가없는 다른 Windows 기본 로그 는 무엇입니까?
ServiceBase.EventLog
. 소스의 기본 이름은 ServiceName입니다.
답변:
예, 찾고있는 이벤트 로그에 쓸 수있는 방법이 있습니다. 새로운 소스를 만들 필요는 없으며, 종종 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를 사용하여 이벤트를 이벤트 로그에 기록하십시오. 이벤트를 작성하려면 이벤트 소스를 지정해야합니다. 소스로 첫 번째 항목을 작성하기 전에 이벤트 소스를 작성하고 구성해야합니다.
MSDN에 명시된대로 (예 : https://msdn.microsoft.com/en-us/library/system.diagnostics.eventlog(v=vs.110).aspx ) 기존 소스가 아닌 소스를 확인하고 소스를 만들려면 관리자가 필요합니다 특권.
그러나 소스 "응용 프로그램" 없이 사용할 수 있습니다. 그러나 Windows 2012 Server r2에서 테스트 한 결과 "응용 프로그램"소스를 사용하여 다음과 같은 로그 항목이 표시됩니다.
소스 애플리케이션의 이벤트 ID xxxx에 대한 설명을 찾을 수 없습니다. 이 이벤트를 발생시키는 구성 요소가 로컬 컴퓨터에 설치되어 있지 않거나 설치가 손상되었습니다. 로컬 컴퓨터에 구성 요소를 설치하거나 복구 할 수 있습니다. 이벤트가 다른 컴퓨터에서 발생한 경우 표시 정보를 이벤트와 함께 저장해야합니다. 다음 정보가 이벤트에 포함되었습니다 : {my event entry message} 메시지 자원이 있지만 메시지가 문자열 / 메시지 테이블에 없습니다
소스를 만들기 위해 다음 방법을 정의했습니다.
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;
}
currentAppName = AppDomain.CurrentDomain.FriendlyName으로 호출합니다.
이 try / catch 대신 EventLogPermission 클래스를 사용할 수 있지만 catch를 피할 수 있는지 확실하지 않습니다.
예를 들어 상위 Powershell과 같이 외부에서 소스를 생성 할 수도 있습니다.
New-EventLog -LogName Application -Source MyApp
그런 다음 위의 방법에서 'MyApp'을 사용하면 예외가 발생하지 않으며 해당 소스로 EventLog를 만들 수 있습니다.
이것은 내가 사용하는 로거 클래스입니다. 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;
}
}
}
시험
System.Diagnostics.EventLog appLog = new System.Diagnostics.EventLog();
appLog.Source = "This Application's Name";
appLog.WriteEntry("An entry to the Application event log.");