Martin Dybal

Vývojářský blog Martina Dybala

Podle kategorie

Aspektově orientované programování – Logování

2. díl - Aspektově orientované programování – Logování

Martin Dybal       20.12.2015       PostSharp a AOP       11880 zobrazení

Jak do projektu jednoduše zavést logování vám ukážu na jednoduché ukázkové aplikaci. Zdrojové soubory si můžete stáhnout zde.

PostSharp nám nabízí velmi jednoduchý způsob jak zavézt logování, téměř bez práce. Klikneme na název metody a rozbalíme možnosti, které nám Visual Studio nabízí. Standartní klávesová zkratka je ctrl+.. Ze seznamu vybereme Add logging.

image

Zobrazí se nám dialog pro nastavení logování. Když klikneme na edit u profilu máme možnost nastavit, co a s jakou prioritou se bude zapisovat do logu.

image

V dalšímu kroku, máme na výběr back end, který chceme k logování použít. Já jsem zvolil knihovnu Log4Net.

image

V další obrazovce je shrnutí co vše PostSharp přidá do projektu.

image

Následuje instalace a dokončení.

K metodě AddEmailAddress se přidal atribut Log a do projektu se přidal soubor PostSharp2.pssln, který obsahuje nastavení logování.

[Log]
public void AddEmailAddress(string email)
{
    if (email.IsEmail())
    {
        emailList.Add(email);
    }
    else
    {
        throw new EmailAddressInInvalidFormat(email);
    }
}

Ještě potřebujeme nastavit Log4Net. Do App.config přidáme dvě sekce. Sekce configSection musí být uvedena jako první sekce hned za tagem <configuration>. Druhou sekcí je nastavení Log4Net. Výsledný App.config vypadá takhle:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net, Culture=neutral" />
  </configSections>

  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
 
  <log4net>
    <appender name="FileAppender" type="log4net.Appender.FileAppender,log4net">
      <file value="Log.txt" />
      <appendToFile value="true" />
      <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %level %logger - %message%newline" />
      </layout>
      <filter type="log4net.Filter.LevelRangeFilter">
        <levelMin value="INFO" />
        <levelMax value="FATAL" />
      </filter>
    </appender>
    <root>
      <level value="DEBUG" />
      <appender-ref ref="FileAppender" />
    </root>
  </log4net>
</configuration>

Ještě musíme do AssemblyInfo.cs přidat dva řádky aby se Log4Net nastavil.

using log4net.Config;

[assembly: XmlConfigurator(Watch = true)]

Aplikaci můžeme spustit

image

vytvoří se nám soubor Log.txt a bude obsahovat jeden řádek.

2014-12-07 22:15:14,549 [1] ERROR PostSharp2.Model.User -   EmailAddressInInvalidFormatException: User.AddEmailAddress(this = {John Doe [email protected]}, string email = "john.doe.gmail.com")

Hromadné použití aspektů

Logování už je funkční, jen by se nám asi moc nelíbilo ke každé funkci dávat atribut [Log]. Proto existuje několik způsobů jak použít atribut plošně. Můžeme uvést atribut nad třídou a tím se aplikuje na všechny její metody.

[Log]
public class JsonUserService : IUserService

To pro naše použití, ale není stále dostatečné. Máme možnost nasadit aspekt na celý jmenný prostor. Do AssemblyInfo.cs přidáme následující dva řádky a smažeme atribut log z metody AddEmailAddress, protože již nebude potřeba.

using PostSharp.Patterns.Diagnostics;

[assembly: Log(AttributeTargetTypes = "PostSharp2.*", AttributePriority = 1)]

Tím použijeme aspekt Log na všech metodách ve jmenném prostoru PostSharp2 a ve všech vnořených jmenných prostorech.

Možnosti filtrování

Ne vždy chceme nastavit atribut úplně na všem. A proto jsou zde široké možnosti filtrování. Parametr AttributeExclude říká, že pro metody vyhovující filtru se aspekt Log nenastaví. AttributePriority určuje pořadí, ve kterém jsou aspekty aplikovány. Dále můžeme použít prefix regex díky tomu můžeme použít pro filtrování regulární výraz.

[assembly: Log(
    AttributePriority = 2,
    AttributeExclude = true,
    AttributeTargetTypes = @"regex:PostSharp2.Extensions.*")]

Také je možné použít filtrování podle modifikátorů tříd. Takhle by vypadalo pravidlo přidávající aspekt všem statickým třídám z jmenného prostoru PostSharp2.

[assembly: Log(AttributeTargetTypes = "PostSharp2.*",
               AttributeTargetTypeAttributes = MulticastAttributes.Static)]

Obdobným způsobem je možné filtrovat podle signatury metody. Například všechny metody s ref parametrem z jmenného prostoru PostSharp2.

[assembly: Log(AttributeTargetTypes = "PostSharp2.*",
               AttributeTargetMemberAttributes = MulticastAttributes.RefParameter)]

V případě že by vám nestačily tyhle možnosti filtrování je možnost u Aspektu přepsat metodu CompileTimeValidate.

public override bool CompileTimeValidate(MethodBase method)
{
    Type targetType = method.DeclaringType;
    if (typeof(IDemandAdminRightToAccess).IsAssignableFrom(targetType))
    {
        Message.Write(targetType, SeverityType.None, "NotSupportedType", "The target type does not implement IUserService.");
        return true;
    }
    return false;
}

Takhle se dá aplikovat aspekt na všechny třídy, které implementují dané rozhraní. Velmi užitečné je to například v případě práv, kdy stačí přidat třídě interface a o zbytek se postaráme v aspektu.

 

hodnocení článku

0       Hodnotit mohou jen registrované uživatelé.

Mohlo by vás také zajímat

 

Nový příspěvek

 

Příspěvky zaslané pod tento článek se neobjeví hned, ale až po schválení administrátorem.

...

Stále mě to nepřesvědčilo o tom, že to není jen zcela zbytečná hovadina na první pohled usnadňující práci, ovšem při bližším pohledu značně omezující.

- Buď to zde není zmíněno, nebo jsem to přehlédl: Podporuje to Visual Basic .NET kód?

- Z toho co jsem pochopil, to zaznamenává neošetřené vyjímky. Pokud ano, ošetřenou vyjímku, kterou potřebuju z nějakého důvodu zaznamenat to nezaznamená?

nahlásit spamnahlásit spam 1 / 3 odpovědětodpovědět

Nevím v čem vás PostSharp omezuje.

PostSharp používá pro připojení aspektů MSIL Injection, takže je na jazyku nezávislý. Budu to rozebírat v příštím článku.

Pokud metoda, v níž dojde k výjimce, výjimku rovnou odchytí, pak ji PostSharp nezaznamená, nemá jak protože PostSharp neupravuje kód metody, on ho pouze obalí dalším kódem, jak bylo znázorněno v prvním článku. V případě že chcete zapisovat do logu i zachycené výjimky nic vám nebrání zapsat si ji do logu přímo v kódu. PostSharp nepokryje stoprocentně všechny případy, ale ušetří vám velké množství opakujícího se kódu.

nahlásit spamnahlásit spam 2 / 4 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.

Nyní zakládáte pod článkem nové diskusní vlákno.
Pokud chcete reagovat na jiný příspěvek, klikněte na tlačítko "Odpovědět" u některého diskusního příspěvku.

Nyní odpovídáte na příspěvek pod článkem. Nebo chcete raději založit nové vlákno?

 

  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

Příspěvky zaslané pod tento článek se neobjeví hned, ale až po schválení administrátorem.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback