log4net nie działa

123

Hej, mam tę konfigurację w moim web.config

<log4net>
    <appender name="LogFileAppender" type="log4net.Appender.FileAppender">
        <param name="File" value="mylog.log" />
        <param name="AppendToFile" value="true" />
        <layout type="log4net.Layout.PatternLayout">
            <param name="Header" value="" />
            <param name="Footer" value="" />
            <param name="ConversionPattern" value="%d [%t] %-5p %m%n" />
        </layout>
    </appender>
    <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
        <layout type="log4net.Layout.PatternLayout">
            <param name="Header" value="[Header]\r\n" />
            <param name="Footer" value="[Footer]\r\n" />
            <param name="ConversionPattern" value="%d [%t] %-5p %m%n" />
        </layout>
    </appender>
    <root>
        <level value="DEBUG" />
        <appender-ref ref="LogFileAppender" />
        <appender-ref ref="ConsoleAppender" />
    </root>
</log4net>

ale log4net nie działa. Mój projekt kompiluje się dobrze i nie pojawiają się żadne błędy podczas debugowania. Wiersze, w których mówię, log.debug("somemessage")działają poprawnie, ale nie mogę znaleźć mylog.logpliku, więc gdzie to jest?

Jakob
źródło
Koniecznie

Odpowiedzi:

298

Jedynym sposobem na tego typu rzeczy jest dodanie XmlConfiguratoratrybutu do zespołu, umieszczając następujący wiersz w swoim AssemblyInfo.cs:

[assembly: log4net.Config.XmlConfigurator]

W przeciwnym razie log4net nigdy się nie aktywuje.

Kirk Woll
źródło
5
Ta metoda używana do pracy w moim projekcie, ale jakoś przestał działać. Musiałem użyć tej metody stackoverflow.com/a/1479343/193634, aby znów działała.
Rosdi Kasim
Po prostu spróbowałem ponownie i działa dobrze. Najprawdopodobniej nie odwołujesz się / nie ładujesz zestawu, który zawiera plik, AssemblyInfotak szybko, jak myślisz.
Kirk Woll,
Dla tych, którzy używają aplikacji ELMAH, jest to droga. Miałem 'log4net.Config.XmlConfigurator.Configure ();' w global.asax.cs i działało dobrze w przypadku programu dołączającego do plików, ale nie w przypadku dołączania ELMAH.
user3885927
Podkreśliłem tę odpowiedź i stwierdziłem, że muszę ją poprawić za pomocą `[assembly: log4net.Config.XmlConfigurator (Watch = true)]`
David Savage
49

Wydaje mi się, że albo log4net w ogóle się nie loguje, albo plik nie kończy się tam, gdzie się tego spodziewasz.

Po pierwsze, czy faktycznie dzwoniłeś

XmlConfigurator.Configure()

gdziekolwiek w Twoim kodzie? Jeśli powyższy fragment kodu XML znajduje się w pliku konfiguracyjnym aplikacji, to wywołanie załatwi sprawę. Jeśli fragment kodu xml znajduje się we własnym pliku, musisz użyć .Configure(string)przeciążenia, które przenosi ścieżkę do pliku. Bez tego wywołania (lub najwyraźniej atrybutu poziomu zespołu, o którym wspomniał Kirk Woll), log4net w ogóle nie będzie rejestrował.

Jeśli uważasz, że to wszystko jest zrobione, a log4net powinien rejestrować, być może powinieneś umieścić pełną ścieżkę do pliku dziennika podczas dalszego debugowania. Dzięki temu będziesz mieć pewność, gdzie powinien znajdować się plik .

Rob Levine
źródło
33

Jest jeszcze jedna mała pułapka, patrz tutaj: http://logging.apache.org/log4net/release/manual/configuration.html#dot-config

ta [assembly: log4net.Config.XmlConfigurator]metoda nie działa z app.config. Jeśli konfigurujesz log4net z app.config, musisz użyć log4net.Config.XmlConfigurator.Configure()metody.

Amir Abiri
źródło
Tak dla przypomnienia, obie metody działały u mnie w aplikacji konsolowej.
rageit
Potwierdzam powyższe rozwiązanie - musiałem wywołać log4net.Config.XmlConfigurator.Configure (); w moim kodzie (który używa app.config, aby log4net działał efektywnie. Linie, które są efektywnie drukowane, to te, które następują po wykonaniu metody Configure ().
luisa rosi
19

Oto moja lista kontrolna, kiedy log4net okazuje się krnąbrny:

  • upewnij się, że plik log4net.config jest kopiowany do folderu bin \ podczas budowania (ustaw na „Kopiuj, jeśli nowszy” w kompilatorze)
    • gdy masz do czynienia z zainstalowanym kodem, upewnij się, że plik log4net.config pojawił się na przejażdżce (ustawiony na „Treść” w kompilatorze)
  • upewnij się, że użytkownik, który działa jako proces, ma prawa do zapisu w folderze, w którym mają być zapisywane dzienniki
  • jeśli masz wątpliwości, daj swobodne uprawnienia c: \ temp \ i zbierz wszystko, aby się tam zalogować ()
  • odpal Sysinternal / Dbgview.exe, aby zobaczyć, czy coś ci powie
Ziemianin42
źródło
3
„upewnij się, że plik log4net.config jest kopiowany do folderu bin \ podczas budowania (w kompilatorze ustawiono opcję„ Kopiuj, jeśli nowszy ”)” -> ocal mój dzień! Wielkie dzięki!
Hoang Nguyen Huu
8

W przypadku dodawania projektu ASP.NET MVC

log4net.Config.XmlConfigurator.Configure();

do Global.asax.cs pomaga również:

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        AuthConfig.RegisterAuth();

        log4net.Config.XmlConfigurator.Configure();
    }
}
Oladipo Olasemo
źródło
1
Miałem z tym bardzo dziwny problem, w produkcji i na komputerze mojego szefa rejestratory działały dobrze w ten sposób, ale dopiero gdy odpowiedź Kirka działała na moim komputerze. Pomyślałem, że dam znać ludziom na wypadek, gdyby mieli podobne problemy (przy okazji projekt MVC).
Shelby 115
@ Shelby115, wielkie dzięki! Próbowałem umieścić moje wpisy log4Net w ELMAH. Miałem wszystko poprawne w web.config. Miałem już 'log4net.Config.XmlConfigurator.Configure ();' w moim global.asax.cs, ale nie będzie działać. Przyszedłem do tego posta SO i dodałem linię do assemblyInfo.cs na podstawie Kirka. Nadal nie działało !. Po przeczytaniu twojego komentarza usunąłem poprzedni wpis z global.asax.cs i zaczął działać. Spędziłem nad tym kilka godzin i Twój komentarz był bardzo pomocny. Dzięki jeszcze raz!
user3885927
Wpis w global.asax.cs działał dobrze w przypadku programu dołączającego plik, ale nie w przypadku programu dołączającego ELMAH. Sposób Kirka działał dla programu ELMAH appender (specjalnie musiałem go usunąć z global.asax.cs)
user3885927
Możesz także chcieć upewnić się, że log4net ma uprawnienia do zapisu w katalogu skonfigurowanym dla plików dziennika.
Oladipo Olasemo
@ Shelby115 Dang, pokochaj to, kiedy zapomnisz rozwiązania, a Twój własny komentarz rozwiązuje Twój problem. Przejście na stronę z odpowiedzią już przez Ciebie przegłosowaną jest również dobrym wskaźnikiem.
Shelby115
7

Oto kroki, które ostatecznie sprawiły, że moje logowanie plików zaczęło działać:

  • -Check AssemblyInfo.cs zawiera następujący atrybut. [zespół: log4net.Config.XmlConfigurator] . Spowoduje to załadowanie log4net.
  • Sprawdź, czy katalog dziennika ma uprawnienia do zapisu.
  • Sprawdź, czy rejestrator ma określony format. Odbywa się to poprzez sprawdzenie, czy każdy element w konfiguracji ma określony element układu . Na przykład:

<appender name="MainLogger"... <layout type="log4net.Layout.SimpleLayout"/>

  • Na koniec spróbuj włączyć wewnętrzne rejestrowanie log4net, aby włączyć rejestrowanie konsoli i sprawdzanie konsoli. Aby to zrobić, dodaj <add key="log4net.Internal.Debug" value="true"/>do swojego appSettings.
Echilon
źródło
<add key = "log4net.Internal.Debug" value = "true" /> Pomogło mi to rozwiązać problem. Dzięki
Ravi Khambhati
Doprowadziły
6

Miałem doświadczenia, w których systemy logowania zawodzą cicho bez wywoływania wyjątków. Przypuszczam, że ma to sens, ponieważ jeśli rejestrator rejestruje błędy, to w jaki sposób może zarejestrować błąd, którego nie może wykonać rejestrowania?

Jeśli więc plik nie został utworzony na dysku, zacznij od sprawdzenia uprawnień systemu plików aby upewnić się, że użytkownik, na którym działa Twoja aplikacja, może zapisać nowy plik w tej lokalizacji na dysku.

Do celów testowych możesz ręcznie utworzyć plik na dysku, który powinien zostać zapisany i otworzyć wszystkim uprawnienia do zapisu. Jeśli rejestrator zacznie do niego zapisywać, wiesz, że jest oparty na pozwoleniach, a nie na konfiguracji.

John K.
źródło
2

Ze swojej strony zapomniałem oznaczyć plik konfiguracyjny do skopiowania podczas kompilacji aplikacji.

Skopiuj plik konfiguracyjny do katalogu wyjściowego

Po prostu kliknij prawym przyciskiem myszy plik log4net.config, wybierz właściwość, a następnie wybierz opcję Kopiuj do katalogu wyjściowego, aby skopiować XXXX

Võ Quang Hòa
źródło
1

Wypróbowałem wszystkie powyższe, ale nic nie działało. Dodanie tej linii w sekcji app.config configSections działało dla mnie.

<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net, Version=1.2.15.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a" />

Upewnij się, że Versioni PublicKeyTokenjest poprawne

Reyan Chougle
źródło
0
<param name="File" value="mylog.log" />

mówi „napisz mylog.log do właściwego folderu”. Oznacza to, że jeśli Twoja aplikacja internetowa jest pod usługą IIS, dziennik zostanie zapisany w C: \ inetpub \ wwwroot \ appname \ mylog.log.

Jeśli nie ma pliku dziennika, być może konto, na którym działa aplikacja, nie ma uprawnień do zapisu w folderze. Możesz uruchomić Process Monitor z SysInternals, aby sprawdzić, czy i gdzie plik jest zapisywany.

Uruchom VS również w trybie debugowania, aby sprawdzić, czy są zgłaszane jakiekolwiek wyjątki (Debug -> Wyjątki -> Wyjątki CLR, sprawdź Zgłoszenie).

Tomas Voracek
źródło
0

W moim przypadku zapomniałem ustawić właściwości pliku log4Net.config na „Treść”, więc plik nie został uwzględniony we wdrożeniu. Więc zwróć na to uwagę:

Compile action : Content
Marco
źródło
0

Niestety żadne z powyższych nie pomogło. Jawna konfiguracja w klasie, która miała być rejestrowana dodatkowo w stosunku do poprzednich sugestii ustawień, załatwiła sprawę.

string assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
log4net.Config.XmlConfigurator.Configure(new FileInfo(assemblyFolder + "/log4net.config"));
Petro Slyvko
źródło
-7

Po kilku godzinach zorientowałem się, dlaczego to nie działa dla mnie ...

miałem:

public static class Program
{

    private static CommunicationManager _bcScanner = new CommunicationManager();
    private static ILog _log = LogManager.GetLogger(typeof(Program));
    private static SocketServer socketListener;

ale powinno być:

public static class Program
    {
        private static ILog _log = LogManager.GetLogger(typeof(Program));
        private static CommunicationManager _bcScanner = new CommunicationManager();
        private static SocketServer socketListener;

Więc upewnij się, że ILog znajduje się w pierwszej linii ....

Jeroen Bakker
źródło
1
To zdecydowanie nie jest przyczyna. Nie ma znaczenia, kiedy inicjalizujesz obiekt ILog, o ile robisz to przed wywołaniem metod rejestrowania, tj. _Log.Info; _log.error itp.
Oladipo Olasemo