Ho una registrazione del database in atto utilizzando AdoNetAppender. Quello che mi piacerebbe fare è registrare l'identità dell'utente su ogni istruzione di registro. Tuttavia, non voglio utilizzare il parametro di identità standard log4net% per due motivi:log4net registrazione del database con parametri personalizzati
- log4net avvisare che è estremamente lento in quanto deve cercare l'identità del contesto.
- In alcuni componenti di servizio l'identità standard è un account di servizio ma abbiamo già acquisito l'identità dell'utente in una variabile e mi piacerebbe usarlo.
ho visto codice in cui alcune persone usano il log4net.ThreadContext per aggiungere ulteriori proprietà ma capisco che questo è 'sicuro' a causa di filo interleaving (ed è anche uno scarico di performance).
Il mio approccio è stato quello di estendere la classe AdoNetAppenderParameter così:
public class UserAdoNetAppenderParameter : AdoNetAppenderParameter
{
public UserAdoNetAppenderParameter()
{
DbType = DbType.String;
PatternLayout layout = new PatternLayout();
Layout2RawLayoutAdapter converter = new Layout2RawLayoutAdapter(layout);
Layout = converter;
ParameterName = "@username";
Size = 255;
}
public override void Prepare(IDbCommand command)
{
command.Parameters.Add(this);
}
public override void FormatValue(IDbCommand command, LoggingEvent loggingEvent)
{
string[] data = loggingEvent.RenderedMessage.Split('~');
string username = data[0];
command.Parameters["@username"] = username;
}
}
e quindi a livello di codice aggiungere questo al appender corrente in questo modo:
ILog myLog = LogManager.GetLogger("ConnectionService");
IAppender[] appenders = myLog.Logger.Repository.GetAppenders();
AdoNetAppender appender = (AdoNetAppender)appenders[0];
appender.AddParameter(new UserAdoNetAppenderParameter());
myLog.InfoFormat("{0}~{1}~{2}~{3}", userName, "ClassName", "Class Method", "Message");
L'intento è quello di utilizzare un formato standard per i messaggi e analizzare la prima parte della stringa che dovrebbe sempre essere il nome utente. Il metodo FormatValue() del parametro appender personalizzato deve quindi utilizzare solo quella parte della stringa in modo che possa essere scritta in un campo separato nel database dei registri.
Il mio problema è che nessuna istruzione di registro viene scritta nel database. Stranamente, durante il debug, un punto di interruzione nel metodo FormatValue() viene colpito solo quando interrompo il servizio.
Ho trascinato un sacco di cose relative a questo ma non ho ancora trovato alcuna risposta. Qualcuno è riuscito a farlo, o sono sulla strada sbagliata. P.S. Ho anche provato ad estendere l'AdoNetAppender ma non ti dà accesso per impostare i valori dei parametri.
Sono tipo bloccato con log4net e ho Window s componenti di servizio nella soluzione che non hanno accesso a HttpContext, sebbene passiamo il nome utente come stringa. Non voglio davvero impostare la proprietà ThreadContext, accedere e quindi annullarla ogni volta che ho bisogno di accedere a qualcosa. Speravo che l'esteso AdoNetAppenderParameter si sarebbe preso cura di esso. Grazie per il tuo suggerimento –