Logowanie wykonanych czynności przez usługę

0

Witam.
Piszę z zapytaniem, czy jest może "szybszy" sposób na logowanie wykonanych czynności przez usługę. Na tę chwilę wszystko ogarniam "ręcznie" poprzez statyczną klasę LOG oraz bibliotekę NLog.

    public static class LOG
    {
        public static void Info(string message)
        {
            LogManager.GetCurrentClassLogger().Info(message);
        }

        public static void Error(Exception ex)
        {
            LogManager.GetCurrentClassLogger().Error(ex);
        }

        public static void Warn(string message)
        {
            LogManager.GetCurrentClassLogger().Warn(message);
        }
    }

W momencie kiedy usługa rozpocznie swoje zadanie, to w kluczowych miejscach dopisuje LOG.Info("<Coś się zrobiło>"). Niekiedy jest tego bardzo dużo, że więcej czasu zajmuje mi opisanie tego w czytelny sposób. Czy są jakieś mechanizmy, które to jakoś "uproszczą"?

1

Może logować do jakiegoś MemCache albo Redis a innym procesem zrzucać logi do plików?

0

Ja to potrzebuje mieć od razu w pliku. Usługa robi pewne operacje na dokumentach, zamawia kurierów poprzez ich API, zarządza zamówieniami z Allegro. Informacje, że coś zostało zrobione, kiedy i dlaczego potrzebuje mieć natychmiastowo, aby mieć argument dla klienta, że "to nie moja wina" ;-) a dodatkowo dla szybkiej reakcji na błędy.

1

Nie bardzo wiem jak sobie wyobrażasz że jakaś biblioteka będzie wiedzieć co ty chcesz mieć w logach.
Jedyne co przychodzi mi na myśl to logowanie kluczowych operacji tzn wywołania do api i odpowiedź od nich, zapytania do bazy i operacje io na plikach.

0

czekaj...

od razu w pliku. nie oznacza tego samego rzędu wielkości co aby mieć argument dla klienta, że "to nie moja wina"

0

@hzmzp: Nie mam wyobrażenia, dlatego pytam tutaj :-)

@WeiXiao To odpowiedź na te "dziwne" cache'owanie co @katakrowa pisał. Choć chyba w dalszym ciągu nie rozumiem jak miałoby mi to pomóc...
Ja mam specyficznych klientów. Większość z nich zawraca mi d... rzeczami, które się nie wydarzyły i aby im to udowodnić potrzebuje mieć jak najwięcej info o wykonanym zadaniu.

0

Można to w jakiś sposób rozwiązać generycznie. Moja propozycja to kontener DI, interceptor do logowania method calli z wybranych serwisów i voila. https://stackoverflow.com/questions/11909117/use-unity-to-intercept-all-calls-to-imyinterface-somemethod

0

Co do głównego pytania to też nie wiem czy jest możliwe jakieś rozwiązanie.
Loguj ładne komunikaty do DB i niech klienci sobie sami oglądają.

0

Nie wiem jak daleko masz zaawansowaną tą aplikację ale ja jestem za stosowaniem podejścia z (Clean Architecture wsparte Serilog a jako sink dodał plik + Seq. Ładnie to zgrywając serializujesz sobie Commands/Queries do log-a i teraz niech się tłumaczą.

Pozdrawiam,
mr-owl

1
AdamWox napisał(a):

Piszę z zapytaniem, czy jest może "szybszy" sposób na logowanie wykonanych czynności przez usługę. Na tę chwilę wszystko ogarniam "ręcznie" poprzez statyczną klasę LOG oraz bibliotekę NLog.

Ten kod jest co najmniej dziwny. Nie dość, ze za każdym wywołaniem tworzysz instancję loggera zamiast stworzyć go raz i trzymać w polu static readonly, to jeszcze utrudniasz sobie analizowanie logów, bo nie da się ich przeglądać filtrując po źródłowej klasie/metodzie, bo wszystkie wpisy pochodzą z jednego miejsca. Każda klasa powinna mieć swój logger.

W momencie kiedy usługa rozpocznie swoje zadanie, to w kluczowych miejscach dopisuje LOG.Info("<Coś się zrobiło>"). Niekiedy jest tego bardzo dużo, że więcej czasu zajmuje mi opisanie tego w czytelny sposób. Czy są jakieś mechanizmy, które to jakoś "uproszczą"?

Nie wiem jakie dokładnie są to błędy ani jakiego rodzaju masz aplikację, ale ja bym zaczął od logowania:

  • requestów przychodzących do aplikacji;
  • requestów wychodzących z aplikacji do innych API;
  • zapytań wysyłanych do bazy;
  • parametrów wywoływanych metod.

Ale jak to zrobić to zależy do tego jaki masz stos technologiczny i jaką architekturę aplikacji. Jeśli używasz ORMa albo masz chociaż jedno miejsce, w którym zachodzi komunikacja z bazą, to łatwo można dany SQL i jego wynik zalogować. Jeśli wszystko jest rozsiane w tysiącu miejsc aplikacji, to będzie żmudne zadanie. Podobnie z ruchem po HTTP - jeśli masz jakąś scentralizowaną fabrykę HttpClientów albo używasz RestSharpa, to będzie łatwe, jak nie to nie. Możliwość automatycznego logowania parametrów metod, o której wspominali koledzy wyżej zależy od tego, czy i jaki kontener IoC używasz.

0

@somekind: Czekałem, aż ktoś się doczepi do tego kodu :D To jest tylko poglądowo, to po pierwsze, a po drugie to nie jest API, tylko Windows Service. Requestów do aplikacji nie ma, ale są requesty na zewnątrz oraz do bazy danych. Dodatkowo jeszcze są metody, które generują dokumenty w Comarch Optima. Na tę chwilę to ja opisuje "ręcznie" ważne linijki kodu. Na przykład rozpoczęcie zadania przez Quartz:

    public class MainJob : IJob
    {
        public async Task Execute(IJobExecutionContext context)
        {
            try
            {
                LOG.Info("Running MainJob");
                LOG.Info("Loading configuration file");
                AppConfig _appConfig = Methods.DeserializeJson<AppConfig>(AllegroService.appConfigPath);
                LOG.Info("Configuration file loaded");
                LOG.Info("Loading documents ready to pack");
                await DocumentsService.GetDocumentsReadyToPack(_appConfig);
                LOG.Info("MainJob finished");
            }
            catch(Exception ex)
            {
                LOG.Error(ex);
            }
        }
    }

W metodzie GetDocumentsReadyToPack() są kolejne takie "wpisy" do pliku z logami, aby mieć cały przebieg zarejestrowany. Jeśli nie ma innej opcji to będę tak pisał. To, że Każda klasa powinna mieć swój logger. jest jakimś nakierowaniem, który zapewne, w jakimś stopniu zmniejszy "klepanie" takich głupot, a zwiększy czytelność głównego kodu.

1 użytkowników online, w tym zalogowanych: 0, gości: 1