Bu olay günlüğüne yazmanın bir yolu var mı:
Ya da en azından olay kaynağı kaydetmem gerekmeyen başka bir Windows varsayılan günlüğü mü?
ServiceBase.EventLog
. Kaynağın varsayılan adı HizmetAdı'dır.
Bu olay günlüğüne yazmanın bir yolu var mı:
Ya da en azından olay kaynağı kaydetmem gerekmeyen başka bir Windows varsayılan günlüğü mü?
ServiceBase.EventLog
. Kaynağın varsayılan adı HizmetAdı'dır.
Yanıtlar:
Evet, aradığınız olay günlüğüne yazmanın bir yolu var. Yeni bir kaynak oluşturmanıza gerek yoktur, yalnızca EventLog adıyla aynı ada sahip olan varolan kaynağı kullanın ve ayrıca bazı durumlarda olay günlüğü Uygulaması gibi yönetimsel ayrıcalıklar olmadan erişilebilir.
* Doğrudan erişemediğiniz diğer durumlar, örneğin yalnızca işletim sistemi tarafından erişilen Güvenlik Olayı Log'udur.
Olay günlüğü uygulamasına doğrudan yazmak için bu kodu kullandım:
using (EventLog eventLog = new EventLog("Application"))
{
eventLog.Source = "Application";
eventLog.WriteEntry("Log message example", EventLogEntryType.Information, 101, 1);
}
Gördüğünüz gibi, EventLog kaynağı EventLog adıyla aynıdır. Bunun nedeni Event Sources @ Windows Dev Center'da bulunabilir (Kaynak adını ifade eden kısmı kalınlaştırdım):
Eventlog anahtarındaki her günlük, olay kaynakları adı verilen alt anahtarları içerir. Olay kaynağı, olayı günlüğe kaydeden yazılımın adıdır. Genellikle uygulamanın adı veya uygulama büyükse uygulamanın bir alt bileşeninin adıdır. Kayıt defterine en fazla 16.384 olay kaynağı ekleyebilirsiniz.
Üzerinde açıklandığı gibi, EventLog sınıfını kullanarak yapabilirsiniz Nasıl yapılır: uygulama olay günlüğüne (Visual C #) için Write :
var appLog = new EventLog("Application");
appLog.Source = "MySource";
appLog.WriteEntry("Test log message");
Ancak, yönetici ayrıcalıklarını kullanarak bu kaynağı "MySource" olarak yapılandırmanız gerekir :
Olay günlüğüne olay yazmak için WriteEvent ve WriteEntry kullanın. Olay yazmak için bir olay kaynağı belirtmelisiniz; kaynakla ilk girişi yazmadan önce olay kaynağını oluşturmanız ve yapılandırmanız gerekir.
MSDN'de belirtildiği gibi (örn. Https://msdn.microsoft.com/en-us/library/system.diagnostics.eventlog(v=vs.110).aspx ), mevcut olmayan bir kaynağı kontrol etmek ve bir kaynak oluşturmak için yönetici gerekir ayrıcalık.
Ancak "Uygulama" kaynağını onsuz kullanmak mümkündür . Windows 2012 Server r2 altındaki testimde, ancak "Uygulama" kaynağını kullanarak aşağıdaki günlük girişini alıyorum:
Kaynak Uygulamadan olay kimliği xxxx için açıklama bulunamadı. Bu olayı başlatan bileşen yerel bilgisayarınıza yüklenmemiş veya yükleme bozulmuş. Bileşeni yerel bilgisayara yükleyebilir veya onarabilirsiniz. Olay başka bir bilgisayardan kaynaklandıysa, görüntüleme bilgilerinin olayla birlikte kaydedilmesi gerekir. Olayla birlikte şu bilgiler eklenmiştir: {olay girdi iletim} ileti kaynağı var, ancak ileti dizede / ileti tablosunda bulunamadı
Kaynağı oluşturmak için aşağıdaki yöntemi tanımladım:
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 ile çağırıyorum
Bu try / catch yerine EventLogPermission sınıfını kullanmak mümkün olabilir, ancak catch'i önleyebileceğimizden emin değiliz.
Kaynağı harici olarak, örneğin yükseltilmiş Powershell'de oluşturmak da mümkündür:
New-EventLog -LogName Application -Source MyApp
Daha sonra, yukarıdaki yöntemde 'Uygulamam' kullanılması istisna oluşturmaz ve EventLog bu kaynakla oluşturulabilir.
Bu kullandığım logger sınıfı. Özel Log () yönteminde, EventLog.WriteEntry()
olay günlüğüne gerçekte böyle yazılır. Bu kodun hepsini buraya dahil ediyorum çünkü kullanışlı. Günlüğe ek olarak, bu sınıf ayrıca iletinin olay günlüğüne yazmak için çok uzun olmadığından da emin olur (iletiyi keser). Mesaj çok uzun olsaydı, bir istisna alırsınız. Arayan ayrıca kaynağı belirtebilir. Arayan bunu yapmazsa, bu sınıf kaynağı alır. Umarım yardımcı olur.
Bu arada, web'den bir ObjectDumper alabilirsiniz. Bunların hepsini buraya göndermek istemedim. Buradan benimkini aldım: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;
}
}
}
Deneyin
System.Diagnostics.EventLog appLog = new System.Diagnostics.EventLog();
appLog.Source = "This Application's Name";
appLog.WriteEntry("An entry to the Application event log.");