Jak skonfigurować log4net programowo od podstaw (bez konfiguracji)
Wiem, że to zły pomysł, ale..... Chcę skonfigurować log4net programowo od podstaw bez pliku konfiguracyjnego. Pracuję nad prostą aplikacją do logowania dla mnie i mojego zespołu, aby użyć jej do kilku stosunkowo małych aplikacji działowych, za które jesteśmy odpowiedzialni. Chcę, żeby wszyscy logowali się do tej samej bazy danych. Aplikacja rejestrująca jest tylko opakowaniem wokół log4net z wstępnie skonfigurowanym AdoNetAppender.
Wszystkie aplikacje są wdrożone ClickOnce, co prezentuje mały problem z instalacją pliku konfiguracyjnego. Jeśli plik konfiguracyjny był częścią projektu core, mógłbym ustawić jego właściwości do wdrożenia wraz z montażem. Ale to część połączonej aplikacji, więc nie mam opcji wdrożenia jej z główną aplikacją. (Jeśli to nie prawda, niech ktoś da mi znać).
Prawdopodobnie dlatego, że jest to zły pomysł, nie ma zbyt wiele przykładowego kodu dostępnego do programowej konfiguracji log4net od podstaw. Oto co mam tak daleko.
Dim apndr As New AdoNetAppender()
apndr.CommandText = "INSERT INTO LOG_ENTRY (LOG_DTM, LOG_LEVEL, LOGGER, MESSAGE, PROGRAM, USER_ID, MACHINE, EXCEPTION) VALUES (@log_date, @log_level, @logger, @message, @program, @user, @machine, @exception)"
apndr.ConnectionString = connectionString
apndr.ConnectionType = "System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
apndr.CommandType = CommandType.Text
Dim logDate As New AdoNetAppenderParameter()
logDate.ParameterName = "@log_date"
logDate.DbType = DbType.DateTime
logDate.Layout = New RawTimeStampLayout()
apndr.AddParameter(logDate)
Dim logLevel As New AdoNetAppenderParameter()
logLevel.ParameterName = "@log_level"
'And so forth...
Po skonfigurowaniu wszystkich parametrów dla apndr
, na początku próbowałem tego...
Dim hier As Hierarchy = DirectCast(LogManager.GetRepository(), Hierarchy)
hier.Root.AddAppender(apndr)
Nie zadziałało. Potem, jako strzał w ciemno, próbowałem tego.
BasicConfigurator.Configure(apndr)
To też nie zadziałało. Czy ktoś ma jakieś dobre referencje jak skonfigurować log4net programowo od podstaw bez pliku konfiguracyjnego? 12 answers
Jednym ze sposobów, w jaki to robiłem w przeszłości, jest dołączenie pliku konfiguracyjnego jako osadzonego zasobu i użycie log4net.Config.Configure (Stream) .
W ten sposób mogłem użyć składni konfiguracji, którą znałem, i nie musiałem się martwić o wdrożenie pliku.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-07 01:35:54
Oto przykładowa klasa, która tworzy konfigurację log4net całkowicie w kodzie. Powinienem wspomnieć, że tworzenie loggera metodą statyczną jest ogólnie postrzegane jako złe, ale w moim kontekście tego właśnie chciałem. Niezależnie od tego, możesz wyrzeźbić kod, aby spełnić swoje potrzeby.
using log4net;
using log4net.Repository.Hierarchy;
using log4net.Core;
using log4net.Appender;
using log4net.Layout;
namespace dnservices.logging
{
public class Logger
{
private PatternLayout _layout = new PatternLayout();
private const string LOG_PATTERN = "%d [%t] %-5p %m%n";
public string DefaultPattern
{
get { return LOG_PATTERN; }
}
public Logger()
{
_layout.ConversionPattern = DefaultPattern;
_layout.ActivateOptions();
}
public PatternLayout DefaultLayout
{
get { return _layout; }
}
public void AddAppender(IAppender appender)
{
Hierarchy hierarchy =
(Hierarchy)LogManager.GetRepository();
hierarchy.Root.AddAppender(appender);
}
static Logger()
{
Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository();
TraceAppender tracer = new TraceAppender();
PatternLayout patternLayout = new PatternLayout();
patternLayout.ConversionPattern = LOG_PATTERN;
patternLayout.ActivateOptions();
tracer.Layout = patternLayout;
tracer.ActivateOptions();
hierarchy.Root.AddAppender(tracer);
RollingFileAppender roller = new RollingFileAppender();
roller.Layout = patternLayout;
roller.AppendToFile = true;
roller.RollingStyle = RollingFileAppender.RollingMode.Size;
roller.MaxSizeRollBackups = 4;
roller.MaximumFileSize = "100KB";
roller.StaticLogFileName = true;
roller.File = "dnservices.txt";
roller.ActivateOptions();
hierarchy.Root.AddAppender(roller);
hierarchy.Root.Level = Level.All;
hierarchy.Configured = true;
}
public static ILog Create()
{
return LogManager.GetLogger("dnservices");
}
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-21 16:56:02
Bardziej zwięzłe rozwiązanie:
var layout = new PatternLayout("%-4timestamp [%thread] %-5level %logger %ndc - %message%newline");
var appender = new RollingFileAppender {
File = "my.log",
Layout = layout
};
layout.ActivateOptions();
appender.ActivateOptions();
BasicConfigurator.Configure(appender);
Nie zapomnij wywołać activateoptions Metoda:
Metoda ActivateOptions musi być wywołana w tym obiekcie Po ustawieniu właściwości konfiguracyjnych. Do momentu wywołania ActivateOptions obiekt ten znajduje się w stanie nieokreślonym i nie może być używany.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-14 00:26:14
Jak mówi Jonathan , Korzystanie z zasobów jest dobrym rozwiązaniem.
Jest to nieco restrykcyjne, ponieważ zawartość osadzonego zasobu zostanie naprawiona podczas kompilacji. Mam komponent logowania, który generuje XmlDocument z podstawową konfiguracją Log4Net, używając zmiennych zdefiniowanych jako appSettings (np. nazwa pliku dla RollingFileAppender, Domyślny poziom logowania, może Nazwa łańcucha połączenia, jeśli chcesz użyć AdoNetAppender). A potem wywołuję log4net.Config.XmlConfigurator.Configure
aby skonfigurować Log4Net używając główny element wygenerowanego dokumentu XmlDocument.
Następnie administratorzy mogą dostosować "standardową" konfigurację, modyfikując kilka ustawień aplikacji (zazwyczaj level, filename, ...) lub może określić zewnętrzny plik konfiguracyjny, aby uzyskać większą kontrolę.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:03
Nie mogę powiedzieć w fragmencie kodu pytania, czy "' i tak dalej..."zawiera bardzo ważny apndr.ActivateOptions (), co jest wskazane w odpowiedzi Todda Stouta. Bez activateoptions() Appender jest nieaktywny i nie zrobi nic, co mogłoby wyjaśnić, dlaczego się nie powiedzie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-03 23:04:48
Dr. Netjes ma to do programowego ustawiania connectionstring:
// Get the Hierarchy object that organizes the loggers
log4net.Repository.Hierarchy.Hierarchy hier =
log4net.LogManager.GetLoggerRepository() as log4net.Repository.Hierarchy.Hierarchy;
if (hier != null)
{
//get ADONetAppender
log4net.Appender.ADONetAppender adoAppender =
(log4net.Appender.ADONetAppender)hier.GetLogger("MyProject",
hier.LoggerFactory).GetAppender("ADONetAppender");
if (adoAppender != null)
{
adoAppender.ConnectionString =
System.Configuration.ConfigurationSettings.AppSettings["MyConnectionString"];
adoAppender.ActivateOptions(); //refresh settings of appender
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-17 12:41:29
Trochę za późno na przyjęcie. Ale tutaj jest minimalny config, który działał dla mnie.
Przykładowa klasa
public class Bar
{
private readonly ILog log = LogManager.GetLogger(typeof(Bar));
public void DoBar() { log.Info("Logged"); }
}
Minimal log4net trace config (inside NUnit test)
[Test]
public void Foo()
{
var tracer = new TraceAppender();
var hierarchy = (Hierarchy)LogManager.GetRepository();
hierarchy.Root.AddAppender(tracer);
var patternLayout = new PatternLayout {ConversionPattern = "%m%n"};
tracer.Layout = patternLayout;
hierarchy.Configured = true;
var bar = new Bar();
bar.DoBar();
}
Drukuje do śledzenia słuchacza
Namespace+Bar: Logged
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-10 13:34:19
// wbudowałem trzy pliki konfiguracyjne jako osadzony zasób i uzyskałem do nich dostęp w następujący sposób:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Resources;
using System.IO;
namespace Loader
{
class Program
{
private static log4net.ILog CustomerLog = log4net.LogManager.GetLogger("CustomerLogging");
private static log4net.ILog OrderLog = log4net.LogManager.GetLogger("OrderLogging");
private static log4net.ILog DetailsLog = log4net.LogManager.GetLogger("OrderDetailLogging");
static void Main(string[] args)
{
// array of embedded log4net config files
string[] configs = { "Customer.config", "Order.config", "Detail.config"};
foreach (var config in configs)
{
// build path to assembly config
StringBuilder sb = new StringBuilder();
sb.Append(System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
sb.Append(".");
sb.Append(config);
// convert to a stream
Stream configStream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(sb.ToString());
// configure logger with ocnfig stream
log4net.Config.XmlConfigurator.Configure(configStream);
// test logging
CustomerLog.Info("Begin logging with: " + config);
OrderLog.Info("Begin logging with: " + config);
DetailsLog.Info("Begin logging with: " + config);
for (int iX = 0; iX < 10; iX++)
{
CustomerLog.Info("iX=" + iX);
OrderLog.Info("iX=" + iX);
DetailsLog.Info("iX=" + iX);
}
CustomerLog.Info("Ending logging with: " + config);
OrderLog.Info("Ending logging with: " + config);
DetailsLog.Info("Ending logging with: " + config);
}
}
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-12 17:54:17
To dziwne, że BasicConfigurator.Configure(apndr)
nie zadziałało. W moim przypadku spełniło swoje zadanie... Ale tak czy siak, oto odpowiedź - powinieneś napisać hier.Configured = true;
(C# code) po zakończeniu konfiguracji.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-24 13:37:28
Skończyło się na tym:
Http://www.mikebevers.be/blog/2010/09/log4net-custom-adonetappender/
Po 4 godzinach majstrowania z konfiguracją i coraz bardziej sfrustrowany.
Mam nadzieję, że to komuś pomoże.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-27 14:43:45
Oto przykład, w jaki sposób można tworzyć i używać AdoNetAdapter
całkowicie w kodzie, całkowicie bez żadnego App.config
pliku (nawet dla Common.Logging
). Śmiało, usuń to!
Ma to dodatkową zaletę, że jest odporny na aktualizacje zgodnie z nowe konwencje nazewnictwa , gdzie nazwa złożenia odzwierciedla teraz wersję. (Common.Logging.Log4Net1213
, itd.)
[SQL]
CREATE TABLE [Log](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Date] [datetime] NOT NULL,
[Thread] [varchar](255) NOT NULL,
[Level] [varchar](20) NOT NULL,
[Source] [varchar](255) NOT NULL,
[Message] [varchar](max) NOT NULL,
[Exception] [varchar](max) NOT NULL
)
[Główna]
Imports log4net
Imports log4net.Core
Imports log4net.Layout
Imports log4net.Config
Imports log4net.Appender
Module Main
Sub Main()
Dim oLogger As ILog
Dim sInput As String
Dim iOops As Integer
BasicConfigurator.Configure(New DbAppender)
oLogger = LogManager.GetLogger(GetType(Main))
Console.Write("Command: ")
Do
Try
sInput = Console.ReadLine.Trim
Select Case sInput.ToUpper
Case "QUIT" : Exit Do
Case "OOPS" : iOops = String.Empty
Case Else : oLogger.Info(sInput)
End Select
Catch ex As Exception
oLogger.Error(ex.Message, ex)
End Try
Console.Clear()
Console.Write("Command: ")
Loop
End Sub
End Module
[DbAppender]
Imports log4net
Imports log4net.Core
Imports log4net.Layout
Imports log4net.Appender
Imports log4net.Repository.Hierarchy
Public Class DbAppender
Inherits AdoNetAppender
Public Sub New()
MyBase.BufferSize = 1
MyBase.CommandText = Me.CommandText
Me.Parameters.ForEach(Sub(Parameter As DbParameter)
MyBase.AddParameter(Parameter)
End Sub)
Me.ActivateOptions()
End Sub
Protected Overrides Function CreateConnection(ConnectionType As Type, ConnectionString As String) As IDbConnection
Return MyBase.CreateConnection(GetType(System.Data.SqlClient.SqlConnection), "Data Source=(local);Initial Catalog=Logger;Persist Security Info=True;User ID=username;Password=password")
End Function
Private Overloads ReadOnly Property CommandText As String
Get
Dim _
sColumns,
sValues As String
sColumns = Join(Me.Parameters.Select(Function(P As DbParameter) P.DbColumn).ToArray, ",")
sValues = Join(Me.Parameters.Select(Function(P As DbParameter) P.ParameterName).ToArray, ",")
Return String.Format(COMMAND_TEXT, sColumns, sValues)
End Get
End Property
Private ReadOnly Property Parameters As List(Of DbParameter)
Get
Parameters = New List(Of DbParameter)
Parameters.Add(Me.LogDate)
Parameters.Add(Me.Thread)
Parameters.Add(Me.Level)
Parameters.Add(Me.Source)
Parameters.Add(Me.Message)
Parameters.Add(Me.Exception)
End Get
End Property
Private ReadOnly Property LogDate As DbParameter
Get
Return New DbParameter("Date", DbType.Date, 0, New DbPatternLayout("%date{yyyy-MM-dd HH:mm:ss.fff}"))
End Get
End Property
Private ReadOnly Property Thread As DbParameter
Get
Return New DbParameter("Thread", DbType.String, 255, New DbPatternLayout("%thread"))
End Get
End Property
Private ReadOnly Property Level As DbParameter
Get
Return New DbParameter("Level", DbType.String, 50, New DbPatternLayout("%level"))
End Get
End Property
Private ReadOnly Property Source As DbParameter
Get
Return New DbParameter("Source", DbType.String, 255, New DbPatternLayout("%logger.%M()"))
End Get
End Property
Private ReadOnly Property Message As DbParameter
Get
Return New DbParameter("Message", DbType.String, 4000, New DbPatternLayout("%message"))
End Get
End Property
Private ReadOnly Property Exception As DbParameter
Get
Return New DbParameter("Exception", DbType.String, 2000, New DbExceptionLayout)
End Get
End Property
Private Const COMMAND_TEXT As String = "INSERT INTO Log ({0}) VALUES ({1})"
End Class
[Dbparametr]
Imports log4net
Imports log4net.Core
Imports log4net.Layout
Imports log4net.Appender
Imports log4net.Repository.Hierarchy
Public Class DbParameter
Inherits AdoNetAppenderParameter
Private ReadOnly Name As String
Public Sub New(Name As String, Type As DbType, Size As Integer, Layout As ILayout)
With New RawLayoutConverter
Me.Layout = .ConvertFrom(Layout)
End With
Me.Name = Name.Replace("@", String.Empty)
Me.ParameterName = String.Format("@{0}", Me.Name)
Me.DbType = Type
Me.Size = Size
End Sub
Public ReadOnly Property DbColumn As String
Get
Return String.Format("[{0}]", Me.Name)
End Get
End Property
End Class
[DbPatternLayout]
Imports log4net
Imports log4net.Core
Imports log4net.Layout
Imports log4net.Appender
Imports log4net.Repository.Hierarchy
Public Class DbPatternLayout
Inherits PatternLayout
Public Sub New(Pattern As String)
Me.ConversionPattern = Pattern
Me.ActivateOptions()
End Sub
End Class
[DbExceptionLayout]
Imports log4net
Imports log4net.Core
Imports log4net.Layout
Imports log4net.Appender
Imports log4net.Repository.Hierarchy
Public Class DbExceptionLayout
Inherits ExceptionLayout
Public Sub New()
Me.ActivateOptions()
End Sub
End Class
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-22 12:21:23
" roztwór do Vb.Net
Private Shared EscanerLog As log4net.ILog = log4net.LogManager.GetLogger("Log4Net.Config")
Public Sub New(ByVal sIDSesion As String)
Dim sStream As Stream
Dim JsText As String
Using reader As New StreamReader((GetType(ClsGestorLogsTraza).Assembly).GetManifestResourceStream("Comun.Log4Net.Config"))
JsText = reader.ReadToEnd()
sStream = GenerateStreamFromString(JsText)
log4net.Config.XmlConfigurator.Configure(sStream)
End Using
End Sub
Public Function GenerateStreamFromString(ByVal s As String) As Stream
Dim stream = New MemoryStream()
Dim writer = New StreamWriter(stream)
writer.Write(s)
writer.Flush()
stream.Position = 0
Return stream
End Function
Public Function StreamFromResource(ByVal sFilename As String) As Stream
Dim nAssembly As System.Reflection.Assembly = System.Reflection.Assembly.GetExecutingAssembly()
Dim s As Stream = nAssembly.GetManifestResourceStream(System.Reflection.MethodBase.GetCurrentMethod.DeclaringType, sFilename)
Return s
End Function
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-14 08:03:13