ASP.NET Control zum Ändern von log4net-Loglevels

1. August 2013

Im nachfolgenden wird ein ASP.NET User Control vorgestellt, mit dessen Hilfe man log4net Loglevels im laufenden Betrieb ändern kann. Dies ist überaus hilfreich um in einer Produktionsumgebung “mal schnell” den LogLevel für spezifische Logger zu erhöhen. Die Funktionsweise habe ich schon in
log4net Levels im laufenden Betrieb ändern
. vorgestellt.  Das Control kann schnell in eine Admin-Seite eingebunden werden und stellt sich wie folgt dar:

LogLevelToggler

LogLevelTogglerControl

Das UserControl zeigt die Daten in einem GridView an. Auf Rocket-Science wird der Einfachheit halber verzichtet und die Daten als One-Way-Binding ohne DataSource realisiert.

   1: <%@ Control  Language="C#" AutoEventWireup="true" 

   2:              CodeBehind="LogLevelTogglerControl.ascx.cs" 

   3:              Inherits="WebAppSystemInfo.LogLevelTogglerControl" %>

   4: <asp:GridView runat="server" ID="gridView" AutoGenerateColumns="false">

   5: <Columns>

   6:   <asp:BoundField ReadOnly="true" HeaderText="Logger" DataField="Name" />

   7:   <asp:BoundField ReadOnly="true" HeaderText="Repository" DataField="Repository" />

   8:   <asp:TemplateField HeaderText="IsFatal" ItemStyle-HorizontalAlign="Center">

   9:   <ItemTemplate>

  10:     <asp:ImageButton runat="server" ImageUrl='<%# GetImage(Eval("IsFatal")) %>' OnCommand="ImgLevel_Command" CommandArgument="IsFatal" CommandName='<%#Eval("Name") %>' />

  11:   </ItemTemplate>

  12:   </asp:TemplateField>

  13:   <asp:TemplateField HeaderText="IsError" ItemStyle-HorizontalAlign="Center">

  14:   <ItemTemplate>

  15:     <asp:ImageButton runat="server" ImageUrl='<%# GetImage(Eval("IsError"))  %>' OnCommand="ImgLevel_Command" CommandArgument="IsError" CommandName='<%#Eval("Name") %>'/>

  16:   </ItemTemplate>

  17:   </asp:TemplateField>

  18:   <asp:TemplateField HeaderText="IsInfo" ItemStyle-HorizontalAlign="Center">

  19:   <ItemTemplate>

  20:     <asp:ImageButton runat="server" ImageUrl='<%# GetImage(Eval("IsInfo")) %>' OnCommand="ImgLevel_Command" CommandArgument="IsInfo" CommandName='<%#Eval("Name") %>'/>

  21:   </ItemTemplate>

  22:   </asp:TemplateField>

  23:   <asp:TemplateField HeaderText="IsDebug" ItemStyle-HorizontalAlign="Center">

  24:   <ItemTemplate>

  25:     <asp:ImageButton runat="server" ImageUrl='<%# GetImage(Eval("IsDebug")) %>' OnCommand="ImgLevel_Command" CommandArgument="IsDebug" CommandName='<%#Eval("Name") %>'/>

  26:   </ItemTemplate>

  27:   </asp:TemplateField>

  28:     <asp:BoundField ReadOnly="True" HeaderText="Defining Logger" DataField="DefiningLogger"/>

  29: </Columns>

  30: </asp:GridView>

ASPX Code: LogLevelTogglerControl.aspx

Im Code-Behind nutzt das Control die Funktionalität des LogLevelToggler.

   1: namespace Sdx.Logging

   2: {

   3:     using System.Web.UI.WebControls;

   4:  

   5:     public partial class LogLevelTogglerControl : System.Web.UI.UserControl

   6:     {

   7:         /// <summary>

   8:         /// Ermittlung des Image

   9:         /// </summary>

  10:         /// <param name="value"></param>

  11:         /// <returns></returns>

  12:         protected string GetImage(object value)

  13:         {

  14:             var state = (bool)value;

  15:             if (state) return "~/Images/Security_Shields_Complete_and_ok_32xLG_color.png";

  16:             return "~/Images/Security_Shields_Critical_32xLG_color.png";

  17:         }

  18:  

  19:         /// <summary>

  20:         /// Ermittelt alle Logger und bindet dieses an das GridView

  21:         /// </summary>

  22:         public override void DataBind()

  23:         {

  24:             base.DataBind();

  25:             var lds = new LogLevelToggler();

  26:             var dataSource = lds.GetLoggerInformation();

  27:             gridView.DataSource = dataSource;

  28:             gridView.DataBind();

  29:         }

  30:  

  31:         /// <summary>

  32:         /// Toggelt den Level

  33:         /// </summary>

  34:         /// <param name="sender"></param>

  35:         /// <param name="e"></param>

  36:         protected void ImgLevel_Command(object sender, CommandEventArgs e)

  37:         {

  38:             // toggle level

  39:             var lm = new LogLevelToggler();

  40:             var rowName = (string)e.CommandArgument;

  41:             var level = LogLevelToggler.LevelMap[rowName];

  42:             lm.ToggleLogLevel(e.CommandName, level);

  43:             // rebind

  44:             this.DataBind();

  45:         }

  46:     }

  47: }

Code-Behind: LogLevelTogglerControl.aspx.cs

Nutzung

Das Control muss jetzt nur noch auf der gewünschten Admin-Seite eingebunden werden.

   1: <%@ Register TagPrefix="ctrl" TagName="LogLevelTogglerControl" Src="~/LogLevelTogglerControl.ascx" %>

   2:  

   3: <ctrl:LogLevelTogglerControl ID="logLevelToggler" runat="server" />

Bitte das Databinding im Codebehind nicht vergessen. Sonst sieht man nichts.

   1: protected void Page_Load(object sender, EventArgs e)

   2: {

   3:     if (! IsPostBack)

   4:     {

   5:         logLevelToggler.DataBind();

   6:     }

   7: }

Fazit

Mit dem vorgestellten Code hat man eine einfache Copy-Paste-Vorlage um LogLevels im laufenden Betrieb umschalten zu können.

Ein ausdrücklicher Gruß geht an mein altes Münchner “Fritten-Buden-Team” wo ich dieses nützliche Prinzip erstmalig gesehen habe.