2008-12-11 5 views
3

J'ai une application Web avec plusieurs services Web. Cette application web a une couche métier et persistance. Est-il possible d'utiliser un appendeur de journaux distinct (fichier journal) par service Web?Utilisation de log4net distinct par service Web/Page

Cela s'applique également aux pages Web. Essentiellement, je veux séparer mes journaux non basés sur la classe ou la couche/l'espace de noms, mais à partir du point d'entrée, qui peut être un service Web ou une page Web.

Répondre

0

Je pourrais le faire en utilisant PropertyFilter. J'ai défini l'appender suivant dans le fichier de configuration:

<appender name="UiFileAppender" type="log4net.Appender.RollingFileAppender"> 
    <file value="Log1.log" /> 
    <appendToFile value="true" /> 
    <rollingStyle value="Size" /> 
    <maxSizeRollBackups value="10" /> 
    <maximumFileSize value="5MB" /> 
    <staticLogFileName value="true" /> 
    <layout type="log4net.Layout.PatternLayout"> 
    <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" /> 
    </layout> 
    <filter type="log4net.Filter.PropertyFilter"> 
    <Key value="channel"/> 
    <StringToMatch value="ui" /> 
    <AcceptOnMatch value="true" /> 
    </filter> 
    <filter type="log4net.Filter.DenyAllFilter" /> 
</appender> 
<appender name="WsFileAppender" type="log4net.Appender.RollingFileAppender"> 
    <file value="Log1.log" /> 
    <appendToFile value="true" /> 
    <rollingStyle value="Size" /> 
    <maxSizeRollBackups value="10" /> 
    <maximumFileSize value="5MB" /> 
    <staticLogFileName value="true" /> 
    <layout type="log4net.Layout.PatternLayout"> 
    <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" /> 
    </layout> 
    <filter type="log4net.Filter.PropertyFilter"> 
    <Key value="channel"/> 
    <StringToMatch value="ws" /> 
    <AcceptOnMatch value="true" /> 
    </filter> 
    <filter type="log4net.Filter.DenyAllFilter" /> 
</appender> 

La partie importante de l'appendeur ci-dessus est des balises.Lorsque l'utilisateur utilise l'interface utilisateur que je mets propriété « canal » à « ui » comme le code suivant:

log4net.GlobalContext.Properties["channel"] = "ui"; 

et lorsque l'utilisateur utilise des services Web que j'utilise le code suivant:

log4net.GlobalContext.Properties["channel"] = "ws"; 

Dois-je définir "channel" propriété sur le plus haut niveau d'entrée lorsque la demande est lancée.

1

Vous pouvez définir enregistreur pour obtenir dans chaque service Web:

namespace log4net 
{ 
    public class LogManager 
    { 
     public static ILog GetLogger(string name); 
     public static ILog GetLogger(Type type); 
    } 
} 

Et puis dans votre application, vous pouvez appeler chaque enregistreur correctement:

public class MyApp 
{ 
    // Define a static logger variable so that it references the 
    // Logger instance named "MyApp". 
private static readonly ILog log = LogManager.GetLogger(typeof(MyApp)); 

static void Main(string[] args) 
{ 
    // Set up a simple configuration that logs on the console. 
    BasicConfigurator.Configure(); 

    log.Info("Entering application."); 
    Bar bar = new Bar(); 
    bar.DoIt(); 
    log.Info("Exiting application."); 
} 
} 

Assurez-vous de changer le typeof à le bon webservice.

Source et Plus d'informations here.

0

Gortok, C'est la façon typique dont nous gérons les journaux. Cependant, je veux dire quelque chose de différent et je pense que je n'étais pas assez clair dans ma question.

Voici un exemple hypothétique: Nous avons une application web qui a quelques pages d'administration et quelques pages client et nous voulons avoir deux fichiers admin.log et customer.log différents pour chaque ensemble de pages. Les deux ensembles de pages utilisent la couche de gestion (y compris CustomerService, OrderService, etc.) et la couche de référentiel CustomerRepository, OrderRepository, etc.). Toutes les couches et classes de l'application sont utilisées dans les deux ensembles de pages, mais nous souhaitons que le journal soit séparé. Cela rend plus facile lorsqu'une exception se produit dans les pages d'administration et que vous parcourez un journal pertinent pour suivre le problème. La solution que vous avez mentionnée est la façon habituelle de journaliser les choses, car lorsque vous utilisez typeof (MyApp) (MyApp étant le nom de la classe ou l'espace de noms) n'indiquera pas quel appender utiliser en fonction de l'utilisateur de la page initié sa demande. Un moyen de gérer cette situation est peut-être d'utiliser un objet de valeur de domaine dans l'application et de définir sa valeur sur le journal approprié lorsque la demande est initiée par l'utilisateur au niveau de l'interface utilisateur et utiliser cette valeur comme paramètre constructeur lorsque vous définissez votre enregistreur dans chaque classe. Mais je me demande s'il y a une meilleure façon de gérer cette approche dans log4net que je ne connais pas.

Ma question est-elle plus claire maintenant?

1

Je suggère d'utiliser Nested Diagnostic Contexts (NDCs) dans chaque page, puis de filtrer la sortie du journal en fonction du NDC.

Les informations NDC seront inclus dans les événements consignés dans le contexte du thread actuel, qui comprendra le code de la page, le code de service, le code référentiel etc.

En utilisant filtering on the NDC content vous pouvez séparer log sortie des différents services.