Return-Path: X-Original-To: apmail-logging-log4net-user-archive@www.apache.org Delivered-To: apmail-logging-log4net-user-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id BA76310DF8 for ; Tue, 17 Sep 2013 13:27:48 +0000 (UTC) Received: (qmail 85870 invoked by uid 500); 17 Sep 2013 13:27:39 -0000 Delivered-To: apmail-logging-log4net-user-archive@logging.apache.org Received: (qmail 85522 invoked by uid 500); 17 Sep 2013 13:27:38 -0000 Mailing-List: contact log4net-user-help@logging.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: "Log4NET User" List-Id: Delivered-To: mailing list log4net-user@logging.apache.org Received: (qmail 85206 invoked by uid 99); 17 Sep 2013 13:27:36 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 17 Sep 2013 13:27:36 +0000 X-ASF-Spam-Status: No, hits=1.5 required=5.0 tests=HTML_MESSAGE,RCVD_IN_DNSWL_LOW,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: domain of dpsenner@gmail.com designates 209.85.212.177 as permitted sender) Received: from [209.85.212.177] (HELO mail-wi0-f177.google.com) (209.85.212.177) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 17 Sep 2013 13:27:24 +0000 Received: by mail-wi0-f177.google.com with SMTP id cb5so4994453wib.10 for ; Tue, 17 Sep 2013 06:27:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:references:in-reply-to:subject:date:message-id:mime-version :content-type:thread-index:content-language; bh=rfUpY1eBttRV3iD/h68zUryz1wAavfdBmYJAaFKF3og=; b=ZIdbJQozzmKdb7wtAyfrCa4ryZrkJRn2F0bioBP8GvKsboDjjrv6gikh7Zv0ZVh8wD sP0sXBzsRc135c+wpd4fEOoL1l1W+HIVM2uaRvpQbbAmtIsy7tMm91GHZo39Z5CVt9nN mawrp1Ajbsh8CqWIamW5NHx8T9z6gj5Q9Kx/EBh9CADTWyEq6Oqa6PPf8cDoEjkXd5/i vsB4+Yhw7aHqwlHzxZ5OOZ+D0ggMcK4imauV71eFlwrv+nX7c9pLU+Toi03xri1D08Gc 9HFI9EeXmtT8rujrvgYWrzHMFXbnSWx//ARNWiTZekhZPiVZER9MFp669D7Ffp5fSPiO nmNw== X-Received: by 10.194.89.233 with SMTP id br9mr26819114wjb.15.1379424424224; Tue, 17 Sep 2013 06:27:04 -0700 (PDT) Received: from C198 ([95.171.44.200]) by mx.google.com with ESMTPSA id hq13sm4460839wib.7.1969.12.31.16.00.00 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Tue, 17 Sep 2013 06:27:03 -0700 (PDT) From: "Dominik Psenner" To: "'Log4NET User'" References: <013001ceb2f8$d2085cc0$76191640$@recombulator.net> <015901ceb36f$87548c90$95fda5b0$@recombulator.net> <003a01ceb372$6524b070$2f6e1150$@gmail.com> <007c01ceb3a6$76488410$62d98c30$@recombulator.net> In-Reply-To: <007c01ceb3a6$76488410$62d98c30$@recombulator.net> Subject: AW: How to configure log4net when using shared assemblies? Date: Tue, 17 Sep 2013 15:26:58 +0200 Message-ID: <007401ceb3a9$96fc11b0$c4f43510$@gmail.com> MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=_NextPart_000_0075_01CEB3BA.5A8AD520" X-Mailer: Microsoft Outlook 15.0 Thread-Index: AQHqE88RoSKOVTktLsJXaieKOJ0HkAHbuEGIAv5W6E0A6xnxdgKk4IqdmU/YmcA= Content-Language: de X-Virus-Checked: Checked by ClamAV on apache.org This is a multipart message in MIME format. ------=_NextPart_000_0075_01CEB3BA.5A8AD520 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit It is not be the job of the libraries to decide which of their log events should be logged, nore how they should be logged. The final product (entry assembly) is the only one who can make a choice whether it wants the log events of its libraries to go into a file, into a database, log only fatals or maybe log everything above info, discard events related to a specific service, .. etc. Von: Anthony Francisco [mailto:ants@recombulator.net] Gesendet: Dienstag, 17. September 2013 15:05 An: 'Log4NET User' Betreff: RE: How to configure log4net when using shared assemblies? SharePoint when you come down to it is simply an ASP.NET application. There are techniques to get loaded up into the ASP.NET application by setting up a global.asax or an IHttpModule, but this kind of change is a farm wide change wide change. Much like I don't have the privileges to change the legacy component or its configuration, I have even less privileges to make a farm wide change. But let's say for a moment that I did have the rights to install a global.asax or IHttpModule, how does that help me? When the legacy component loads up its configuration, won't it just go and override the configuration I setup in my global.asax or IHttpModule? Or is there a way to lock down a hierarchy once it's been configured once? Another way to think of my general problem is that you are writing two addins for Word (ABC.Xena.dll and ABC.Gabrielle.dll) which can be either bought by customers together or separately. Your two addins depend on a common utility assembly (ABC.Joxer.dll) . All your assemblies use log4net. Additionally, the customer also has another addin they bought from a 3rd party (XYZ.Calisto.dll) that also uses log4net, but the 3rd party had configured theirs to use the root level logger. So obviously you don't want your log output going into the 3rd party's log file, nor do you want the 3rd party's log output to go into your logfile. Additionally, you'll want the log output for the two addins to be complete so that if there is an issue, the customer only needs to email just one log file (eg. ABC.Xena.log contains output from ABC.Xena and ABC.Joxer, and ABC.Gabrielle.log contains output from ABC.Gabrielle and ABC.Joxer.) - Ants From: Dominik Psenner [mailto:dpsenner@gmail.com] Sent: Tuesday, 17 September, 2013 02:52 To: 'Log4NET User' Subject: AW: How to configure log4net when using shared assemblies? There is always a main entry point. That entry point (assembly) knows which assemblies it may will load during runtime and that entry point is usually the place where logging is configured. In case of a console application that place would be the first line in Main(string[] argv), in case of a WPF application it would be App.xaml.cs or the MainWindow constructor etc. I'm not familiar enough with SharePoint to know what that entry point will be. Von: Anthony Francisco [mailto:ants@recombulator.net] Gesendet: Dienstag, 17. September 2013 08:31 An: 'Log4NET User' Betreff: RE: How to configure log4net when using shared assemblies? There are three reasons: 1. I cannot touch the configuration of the legacy component. 2. I can't predict ahead of time which assembly will be the entry assembly. 3. The hosting application is actually SharePoint, I can't touch that code ited. - Anthony From: Dominik Psenner [mailto:dpsenner@gmail.com] Sent: Monday, 16 September, 2013 18:07 To: Log4NET User Subject: Re: How to configure log4net when using shared assemblies? Why don't you configure logging only in the entry assembly? 2013/9/16 Anthony Francisco > (I've also posted this question to StackOverflow .) How do I configure log4net when I'm using shared assemblies? I have multiple components which depend on common component. Each of the components lives in its own assembly. All the components use log4net for logging. All the components are loaded into a single process space, but the order of usage of the components varies. All the outfacing components load their respective log4net configurations on first use to try to send logging data to their. The common component does not load any configuration. Additionally, there is a legacy component which does not use the common component. It also outfacing and loads its configuration on first use. I cannot touch the code or configuration of this legacy component directly. The problem I'm facing is that due to the components loading their configuration on first use, the last person to load the configuration wins. This results in logging happening, but all the log output ends up going into that last configuration that loaded. Obviously, it's just ugly to look in your log file and have some other component's log entries written into it. I've hit upon a partial solution by using the RepositoryAttribute and AliasRepositoryAttribute. The lets the outfacing components load their configuration into their "logger repository", and effectively isolate themselves from each other. The legacy component now happily writes to its own logs without an noise from my components, and my components are happily writing to their own logs without generating noise in the other logs. I said partial solution because there still exists the situation for logging for the common component. When using the AliasRepositoryAttribute, the first component that is loaded and aliases the common component gets all the log output even if it was another component that was calling into the common component. This is terrible since I'll be missing important logging information in the later components, and I'll have non relevant logging information in the first log. The following code demonstrates the issue: Common: (stand in for the common component) using System; using System.Collections.Generic; using System.Linq; using System.Text; using log4net; using log4net.Config; [assembly: Repository("CommonLib")] namespace CommonLib { public class CommonClass { static readonly ILog Log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().Declari ngType); public void DoCommon(string from) { Log.Debug("DoCommon:" + from); } } } Library A: (stand in for one of the outfacing components) using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml; using CommonLib; using log4net; using log4net.Config; [assembly: Repository("ALib")] [assembly: AliasRepository("CommonLib")] namespace ALib { public static class LogPrep { static bool _loaded = false; public static void Ensure() { if (_loaded) return; var doc = new XmlDocument(); doc.LoadXml( @" "); XmlConfigurator.Configure(doc.DocumentElement); _loaded = true; } } public class AClass { static readonly ILog Log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().Declari ngType); public void DoA() { LogPrep.Ensure(); Log.Debug("DoA"); var common = new CommonClass(); common.DoCommon("A"); } } } Library B: (stand in for another outfacing component) using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml; using CommonLib; using log4net; using log4net.Config; [assembly: Repository("BLib")] [assembly: AliasRepository("CommonLib")] namespace BLib { public class BClass { static readonly ILog Log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().Declari ngType); public static class LogPrep { static bool _loaded = false; public static void Ensure() { if (_loaded) return; var doc = new XmlDocument(); doc.LoadXml( @" "); XmlConfigurator.Configure(doc.DocumentElement); _loaded = true; } } public void DoB() { LogPrep.Ensure(); Log.Debug("DoB"); var common = new CommonClass(); common.DoCommon("B"); } } } Executable container: (stand in for the legacy component) using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml; using System.Xml.Linq; using ALib; using BLib; using log4net; using log4net.Config; namespace TestLog4NetRepositories { class Program { private static readonly ILog Log = LogManager.GetLogger(typeof(Program)); static void Main(string[] args) { // Set up a simple configuration that logs on the console. var doc = new XmlDocument(); doc.LoadXml( @" "); XmlConfigurator.Configure(doc.DocumentElement); Log.Info("Entering application."); var a = new AClass(); a.DoA(); var b = new BClass(); b.DoB(); Log.Info("Exiting application."); } } } If you run this code, notice that Common's output is printed out in Green, and never printed out in Red. log4net: Creating repository [BLib] using type [log4net.Repository.Hierarchy.Hierarchy] log4net:ERROR Failed to alias repository [CommonLib] System.InvalidOperationException: Repository [CommonLib] is already aliased to repository [ALib]. Aliases cannot be redefined. at log4net.Core.DefaultRepositorySelector.AliasRepository(String repositoryAlias, ILoggerRepository repositoryTarget) at log4net.Core.DefaultRepositorySelector.LoadAliases(Assembly assembly, ILoggerRepository repository) Although the executable container above shows A before B, in the real situation, B can be before A. As I mentioned before, I have more complex hierarchy, but the above demonstrates the minimal problem I am facing. -- Dominik Psenner ------=_NextPart_000_0075_01CEB3BA.5A8AD520 Content-Type: text/html; charset="us-ascii" Content-Transfer-Encoding: quoted-printable

It is not be the job of the libraries to = decide which of their log events should be logged, nore how they should = be logged. The final product (entry assembly) is the only one who can = make a choice whether it wants the log events of its libraries to go = into a file, into a database, log only fatals or maybe log everything = above info, discard events related to a specific service, .. = etc.

 

Von:= = Anthony Francisco [mailto:ants@recombulator.net]
Gesendet: = Dienstag, 17. September 2013 15:05
An: 'Log4NET = User'
Betreff: RE: How to configure log4net when using shared = assemblies?

 

SharePoint when you come down to it is simply an ASP.NET = application.

 

There are techniques to get loaded up into the ASP.NET application by = setting up a global.asax or an IHttpModule, but this kind of change is a = farm wide change  wide change. Much like I don’t have the = privileges to change the legacy component or its configuration, I have = even less privileges to make a farm wide change.

 

But let’s say for a moment that I did have the rights to = install a global.asax or IHttpModule, how does that help me? When the = legacy component loads up its configuration, won’t it just go and = override the configuration I setup in my global.asax or IHttpModule? Or = is there a way to lock down a hierarchy once it’s been configured = once?

 

Another way to think of my general problem is that you are writing = two addins for Word (ABC.Xena.dll and ABC.Gabrielle.dll) which can be = either bought by customers together or separately. Your two addins = depend on a common utility assembly (ABC.Joxer.dll) . All your = assemblies use log4net. Additionally, the customer also has another = addin they bought from a 3rd party (XYZ.Calisto.dll) that = also uses log4net, but the 3rd party had configured theirs to = use the root level logger. So obviously you don’t want your log = output going into the 3rd party’s log file, nor do you = want the 3rd party’s log output to go into your = logfile. Additionally, you’ll want the log output for the two = addins to be complete so that if there is an issue, the customer only = needs to email just one log file (eg. ABC.Xena.log contains output from = ABC.Xena and ABC.Joxer, and ABC.Gabrielle.log contains output from = ABC.Gabrielle and ABC.Joxer.)

 

-          = Ants

 

From:= Dominik = Psenner [mailto:dpsenner@gmail.com] =
Sent: Tuesday, 17 September, 2013 02:52
To: = 'Log4NET User'
Subject: AW: How to configure log4net when = using shared assemblies?

 

There is always a main entry point. That entry point (assembly) knows = which assemblies it may will load during runtime and that entry point is = usually the place where logging is configured.

 

In case of a console application that place would be the first line = in Main(string[] argv), in case of a WPF application it would be = App.xaml.cs or the MainWindow constructor etc.

 

I’m not familiar enough with SharePoint to know what that entry = point will be.

 

Von:= = Anthony Francisco [mailto:ants@recombulator.net] =
Gesendet: Dienstag, 17. September 2013 08:31
An: = 'Log4NET User'
Betreff: RE: How to configure log4net when = using shared assemblies?

 

There are three reasons:

1. I cannot touch the configuration of the legacy = component.

2. I can’t predict ahead of time which assembly will be the = entry assembly.

3. The hosting application is actually SharePoint, I can’t = touch that code ited.

 

- Anthony

 

From:= Dominik = Psenner [mailto:dpsenner@gmail.com] =
Sent: Monday, 16 September, 2013 18:07
To: Log4NET = User
Subject: Re: How to configure log4net when using shared = assemblies?

 

Why don't you configure logging only in the entry = assembly?

 

2013/9/16 Anthony Francisco <ants@recombulator.net>

(I’ve also posted this question to StackOverflow.)

 

How do I = configure log4net when I'm using shared assemblies?

I have = multiple components which depend on common component. Each of the = components lives in its own assembly. All the components use log4net for = logging. All the components are loaded into a single process space, but = the order of usage of the components varies. All the outfacing = components load their respective log4net configurations on first use to = try to send logging data to their. The common component does not load = any configuration. Additionally, there is a legacy component which does = not use the common component. It also outfacing and loads its = configuration on first use. I cannot touch the code or configuration of = this legacy component directly.

The problem = I'm facing is that due to the components loading their configuration on = first use, the last person to load the configuration wins. This results = in logging happening, but all the log output ends up going into that = last configuration that loaded. Obviously, it's just ugly to look in = your log file and have some other component's log entries written into = it.

I've hit = upon a partial solution by using the RepositoryAttribute and = AliasRepositoryAttribute. The lets the outfacing components load their = configuration into their "logger repository", and effectively = isolate themselves from each other. The legacy component now happily = writes to its own logs without an noise from my components, and my = components are happily writing to their own logs without generating = noise in the other logs.

I said = partial solution because there still exists the situation for logging = for the common component. When using the AliasRepositoryAttribute, the = first component that is loaded and aliases the common component gets all = the log output even if it was another component that was calling into = the common component. This is terrible since I'll be missing important = logging information in the later components, and I'll have non relevant = logging information in the first log.

The = following code demonstrates the issue:

Common: = (stand in for the common component)

using System;

using = System.Collections.Generic;

using System.Linq;

using System.Text;

using log4net;

using log4net.Config;

[assembly: = Repository("CommonLib")]

 

namespace CommonLib

{

    public class = CommonClass

    {

      = ;  static readonly ILog Log =3D = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().Decl= aringType);

 

      = ;  public void DoCommon(string from)

      = ;  {

      = ;      Log.Debug("DoCommon:" + = from);

      = ;  }

    }

}

Library A: = (stand in for one of the outfacing components)

using System;

using = System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Xml;

using CommonLib;

using log4net;

using log4net.Config;

[assembly: = Repository("ALib")]

[assembly: = AliasRepository("CommonLib")]

 

namespace ALib

{

    public static = class LogPrep

    {

      = ;  static bool _loaded =3D false;

 

      = ;  public static void Ensure()

      = ;  {

      = ;      if (_loaded)

      = ;          = return;

 

      = ;      var doc =3D new = XmlDocument();

      = ;      doc.LoadXml(

@"<log4net = xsi:noNamespaceSchemaLocation=3D'http://csharptest.net/downloads/schema/log4net.xsd'=

      = ;   xmlns:xsi=3D'http://www.w3.org/2001/XMLSchema-instance'

      = ;   debug=3D'true'>

  <appender = name=3D'ConsoleAppender' = type=3D'log4net.Appender.ColoredConsoleAppender'>

    = <mapping>

      = ;  <level value=3D'DEBUG' />

      = ;  <foreColor value=3D'White' />

      = ;  <backColor value=3D'Green' />

    = </mapping>

    <layout = type=3D'log4net.Layout.PatternLayout'>

      = <conversionPattern value=3D'ALib: %d{yyyy MMM dd HH:mm:ss} [%p] %c{1} = %mdc - %m%n' />

    = </layout>

  = </appender>

  <root>

    <level = value=3D'DEBUG' />

    = <appender-ref ref=3D'ConsoleAppender' />

  </root>

</log4net>");

      = ;      = XmlConfigurator.Configure(doc.DocumentElement);

 

      = ;      _loaded =3D true;

      = ;  }

    }

 

    public class = AClass

    {

      = ;  static readonly ILog Log =3D = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().Decl= aringType);

 

      = ;  public void DoA()

      = ; {

      = ;      LogPrep.Ensure();

      = ;      Log.Debug("DoA");

 

      = ;      var common =3D new = CommonClass();

      = ;      = common.DoCommon("A");

      = ;  }

    }

}

Library B: = (stand in for another outfacing component)

using System;

using = System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Xml;

using CommonLib;

using log4net;

using log4net.Config;

[assembly: = Repository("BLib")]

[assembly: = AliasRepository("CommonLib")]

 

namespace BLib

{

    public class = BClass

    {

      = ;  static readonly ILog Log =3D = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().Decl= aringType);

 

      = ;  public static class LogPrep

      = ;  {

      = ;      static bool _loaded =3D = false;

 

      = ;      public static void Ensure()

      = ;      {

      = ;         if = (_loaded)

      = ;            =   return;

 

      = ;          var doc =3D new = XmlDocument();

      = ;          = doc.LoadXml(

@"<log4net = xsi:noNamespaceSchemaLocation=3D'http://csharptest.net/downloads/schema/log4net.xsd'=

      = ;   xmlns:xsi=3D'http://www.w3.org/2001/XMLSchema-instance'

      = ;   debug=3D'true'>

  <appender = name=3D'ConsoleAppender' = type=3D'log4net.Appender.ColoredConsoleAppender'>

    = <mapping>

      = ;  <level value=3D'DEBUG' />

      = ;  <foreColor value=3D'White' />

      = ;  <backColor value=3D'Red' />

  =   </mapping>

    <layout = type=3D'log4net.Layout.PatternLayout'>

      = <conversionPattern value=3D'BLib: %d{yyyy MMM dd HH:mm:ss} [%p] %c{1} = %mdc - %m%n' />

    = </layout>

  = </appender>

  <root>

    <level = value=3D'DEBUG' />

    = <appender-ref ref=3D'ConsoleAppender' />

  </root>

</log4net>");

      = ;          = XmlConfigurator.Configure(doc.DocumentElement);

 

      = ;          _loaded =3D = true;

      = ;      }

      = ;  }

 

      = ;  public void DoB()

      = ;  {

      = ;      LogPrep.Ensure();

      =       Log.Debug("DoB");

 

      = ;      var common =3D new = CommonClass();

      = ;      = common.DoCommon("B");

      = ;  }

    }

}

Executable = container: (stand in for the legacy component)

using System;

using = System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Xml;

using System.Xml.Linq;

using ALib;

using BLib;

using log4net;

using log4net.Config;

 

namespace = TestLog4NetRepositories

{

    class = Program

    {

      = ;  private static readonly ILog Log =3D = LogManager.GetLogger(typeof(Program));

 

      = ; static void Main(string[] args)

      = ;  {

 

      = ;      // Set up a simple configuration that = logs on the console.

 

      = ;      var doc =3D new = XmlDocument();

      = ;      doc.LoadXml(

@"<log4net = xsi:noNamespaceSchemaLocation=3D'http://csharptest.net/downloads/schema/log4net.xsd'=

      = ;   xmlns:xsi=3D'http://www.w3.org/2001/XMLSchema-instance'

      = ;   debug=3D'true'>

  <appender = name=3D'ConsoleAppender' = type=3D'log4net.Appender.ColoredConsoleAppender'>

    = <mapping>

      = ;  <level value=3D'DEBUG' />

      = ;  <foreColor value=3D'White' />

      = ;  <backColor value=3D'Blue' />

    = </mapping>

    <layout = type=3D'log4net.Layout.PatternLayout'>

      = <conversionPattern value=3D'Main: %d{yyyy MMM dd HH:mm:ss} [%p] %c{1} = %mdc - %m%n' />

    = </layout>

  = </appender>

  <root>

    <level = value=3D'DEBUG' />

    = <appender-ref ref=3D'ConsoleAppender' />

  </root>

</log4net>");

      = ;      = XmlConfigurator.Configure(doc.DocumentElement);

 

      = ;      Log.Info("Entering = application.");

 

      = ;      var a =3D new AClass();

      = ;      a.DoA();

 

      = ;     var b =3D new BClass();

      = ;      b.DoB();

 

      = ;      Log.Info("Exiting = application.");

      = ;  }

    }

}

If you run = this code, notice that Common's output is printed out in Green, and = never printed out in Red.

log4net: Creating repository = [BLib] using type [log4net.Repository.Hierarchy.Hierarchy]

log4net:ERROR Failed to alias = repository [CommonLib] System.InvalidOperationException: Repository = [CommonLib] is already aliased to repository [ALib]. Aliases cannot be = redefined.

    at = log4net.Core.DefaultRepositorySelector.AliasRepository(String = repositoryAlias, ILoggerRepository repositoryTarget)

    at = log4net.Core.DefaultRepositorySelector.LoadAliases(Assembly assembly, = ILoggerRepository repository)

Although the = executable container above shows A before B, in the real situation, B = can be before A.

As I = mentioned before, I have more complex hierarchy, but the above = demonstrates the minimal problem I am facing.

 



 

--

Dominik = Psenner

------=_NextPart_000_0075_01CEB3BA.5A8AD520--