Dziennik aplikacji ze strukturą dla usługi Azure Spring Apps

Uwaga

Azure Spring Apps to nowa nazwa usługi Azure Spring Cloud. Mimo że usługa ma nową nazwę, stara nazwa będzie widoczna w niektórych miejscach przez pewien czas, ponieważ pracujemy nad aktualizowaniem zasobów, takich jak zrzuty ekranu, filmy wideo i diagramy.

Ten artykuł dotyczy: ✔️ Podstawowa/Standardowa ✔️ Enterprise

W tym artykule wyjaśniono, jak generować i zbierać dane dziennika aplikacji ustrukturyzowanych w usłudze Azure Spring Apps. Dzięki odpowiedniej konfiguracji usługa Azure Spring Apps udostępnia przydatne zapytania dziennika aplikacji i analizę za pośrednictwem usługi Log Analytics.

Wymagania dotyczące schematu dziennika

Aby ulepszyć środowisko zapytań dziennika, dziennik aplikacji musi być w formacie JSON i być zgodny ze schematem. Usługa Azure Spring Apps używa tego schematu do analizowania aplikacji i przesyłania strumieniowego do usługi Log Analytics.

Uwaga

Włączenie formatu dziennika JSON utrudnia odczytywanie danych wyjściowych przesyłania strumieniowego dziennika z konsoli. Aby uzyskać dane wyjściowe czytelne dla człowieka, dołącz --format-json argument do polecenia interfejsu az spring app logs wiersza polecenia. Zobacz Formatowanie dzienników strukturalnych JSON.

Wymagania dotyczące schematu JSON:

Klucz Json Typ wartości JSON Wymagania Kolumna w usłudze Log Analytics opis
timestamp string Tak AppTimestamp znacznik czasu w formacie UTC
Rejestratora string Nie Rejestratora Rejestratora
poziom string Nie Niestandardowy poziom poziom dziennika
wątek string Nie Wątek wątek
wiadomość string Nie Wiadomość komunikat dziennika
Stacktrace string Nie StackTrace ślad stosu wyjątków
exceptionClass string Nie ExceptionClass nazwa klasy wyjątku
Mdc zagnieżdżony kod JSON Nie. mapowany kontekst diagnostyczny
mdc.traceId string Nie Traceid identyfikator śledzenia dla śledzenia rozproszonego
mdc.spanId string Nie SpanId identyfikator zakresu dla śledzenia rozproszonego
  • Pole "sygnatura czasowa" jest wymagane i powinno być w formacie UTC, wszystkie inne pola są opcjonalne.
  • "traceId" i "spanId" w polu "mdc" są używane do celów śledzenia.
  • Rejestruje każdy rekord JSON w jednym wierszu.

Przykład rekordu dziennika

{"timestamp":"2021-01-08T09:23:51.280Z","logger":"com.example.demo.HelloController","level":"ERROR","thread":"http-nio-1456-exec-4","mdc":{"traceId":"c84f8a897041f634","spanId":"c84f8a897041f634"},"stackTrace":"java.lang.RuntimeException: get an exception\r\n\tat com.example.demo.HelloController.throwEx(HelloController.java:54)\r\n\","message":"Got an exception","exceptionClass":"RuntimeException"}

Ograniczenia

Każdy wiersz dzienników JSON ma co najwyżej 16 K bajtów. Jeśli dane wyjściowe JSON pojedynczego rekordu dziennika przekraczają ten limit, jest on podzielony na wiele wierszy, a każdy nieprzetworzony wiersz jest zbierany do Log kolumny bez analizowania strukturalnego.

Ogólnie rzecz biorąc, ta sytuacja występuje w przypadku rejestrowania wyjątków z głębokim stostrace, zwłaszcza gdy aplikacja Szczegółowe informacje agent in-process jest włączony. Zastosuj ustawienia limitu do danych wyjściowych stostrace (zobacz poniższe przykłady konfiguracji), aby upewnić się, że końcowe dane wyjściowe zostaną prawidłowo przeanalizowane.

Generowanie dziennika JSON zgodnego ze schematem

W przypadku aplikacji Spring można wygenerować oczekiwany format dziennika JSON przy użyciu typowych struktur rejestrowania, takich jak Logback i Log4j2.

Rejestrowanie przy użyciu logback

W przypadku korzystania z szablonów startowych Spring Boot usługa Logback jest domyślnie używana. W przypadku aplikacji Logback użyj kodera logstash-encoder do wygenerowania dziennika sformatowanego w formacie JSON. Ta metoda jest obsługiwana w środowisku Spring Boot w wersji 2.1 lub nowszej.

Procedura:

  1. Dodaj zależność logstash w pom.xml pliku.

    <dependency>
        <groupId>net.logstash.logback</groupId>
        <artifactId>logstash-logback-encoder</artifactId>
        <version>6.5</version>
    </dependency>
    
  2. logback-spring.xml Zaktualizuj plik konfiguracji, aby ustawić format JSON.

    <configuration>
        <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
            <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
                <providers>
                    <timestamp>
                        <fieldName>timestamp</fieldName>
                        <timeZone>UTC</timeZone>
                    </timestamp>
                    <loggerName>
                        <fieldName>logger</fieldName>
                    </loggerName>
                    <logLevel>
                        <fieldName>level</fieldName>
                    </logLevel>
                    <threadName>
                        <fieldName>thread</fieldName>
                    </threadName>
                    <nestedField>
                        <fieldName>mdc</fieldName>
                        <providers>
                            <mdc />
                        </providers>
                    </nestedField>
                    <stackTrace>
                        <fieldName>stackTrace</fieldName>
                        <!-- maxLength - limit the length of the stack trace -->
                        <throwableConverter class="net.logstash.logback.stacktrace.ShortenedThrowableConverter">
                            <maxDepthPerThrowable>200</maxDepthPerThrowable>
                            <maxLength>14000</maxLength>
                            <rootCauseFirst>true</rootCauseFirst>
                        </throwableConverter>
                    </stackTrace>
                    <message />
                    <throwableClassName>
                        <fieldName>exceptionClass</fieldName>
                    </throwableClassName>
                </providers>
            </encoder>
        </appender>
        <root level="info">
            <appender-ref ref="stdout" />
        </root>
    </configuration>
    
  3. W przypadku korzystania z pliku konfiguracji rejestrowania z sufiksem -spring , na logback-spring.xmlprzykład , można ustawić konfigurację rejestrowania na podstawie profilu Aktywnego spring.

    <configuration>
        <springProfile name="dev">
            <!-- JSON appender definitions for local development, in human readable format -->
            <include resource="org/springframework/boot/logging/logback/defaults.xml" />
            <include resource="org/springframework/boot/logging/logback/console-appender.xml" />
            <root level="info">
                <appender-ref ref="CONSOLE" />
            </root>
        </springProfile>
    
        <springProfile name="!dev">
            <!-- JSON appender configuration from previous step, used for staging / production -->
            ...
        </springProfile>
    </configuration>
    

    W przypadku programowania lokalnego uruchom aplikację Spring z argumentem -Dspring.profiles.active=devJVM , a następnie możesz wyświetlić dzienniki czytelne dla człowieka zamiast wierszy sformatowanych w formacie JSON.

Rejestrowanie przy użyciu log4j2

W przypadku aplikacji log4j2 użyj formatu json-template-layout do generowania dziennika sformatowanego w formacie JSON. Ta metoda jest obsługiwana w środowisku Spring Boot w wersji 2.1 lub nowszej.

Procedura:

  1. Wyklucz z pliku , dodaj zależności log4j-layout-template-jsonspring-boot-starter-log4j2w plikupom.xml.spring-boot-starterspring-boot-starter-logging

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-log4j2</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-layout-template-json</artifactId>
        <version>2.14.0</version>
    </dependency>
    
  2. Przygotuj plik jsonTemplate.json szablonu układu JSON w ścieżce klasy.

    {
        "mdc": {
            "$resolver": "mdc"
        },
        "exceptionClass": {
            "$resolver": "exception",
            "field": "className"
        },
        "stackTrace": {
            "$resolver": "exception",
            "field": "stackTrace",
            "stringified": true
        },
        "message": {
            "$resolver": "message",
            "stringified": true
        },
        "thread": {
            "$resolver": "thread",
            "field": "name"
        },
        "timestamp": {
            "$resolver": "timestamp",
            "pattern": {
                "format": "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
                "timeZone": "UTC"
            }
        },
        "level": {
            "$resolver": "level",
            "field": "name"
        },
        "logger": {
            "$resolver": "logger",
            "field": "name"
        }
    }
    
  3. Użyj tego szablonu układu JSON w log4j2-spring.xml pliku konfiguracji.

    <configuration>
        <appenders>
            <console name="Console" target="SYSTEM_OUT">
                <!-- maxStringLength - limit the length of the stack trace -->
                <JsonTemplateLayout eventTemplateUri="classpath:jsonTemplate.json" maxStringLength="14000" />
            </console>
        </appenders>
        <loggers>
            <root level="info">
                <appender-ref ref="Console" />
            </root>
        </loggers>
    </configuration>
    

Analizowanie dzienników w usłudze Log Analytics

Po prawidłowej konfiguracji aplikacji dziennik konsoli aplikacji jest przesyłany strumieniowo do usługi Log Analytics. Struktura umożliwia wydajne wykonywanie zapytań w usłudze Log Analytics.

Sprawdzanie struktury dziennika w usłudze Log Analytics

Postępuj zgodnie z następującą procedurą:

  1. Przejdź do strony przeglądu usługi wystąpienia usługi.

  2. Wybierz wpis Dzienniki w sekcji Monitorowanie.

  3. Uruchom to zapytanie.

    AppPlatformLogsforSpring
    | where TimeGenerated > ago(1h)
    | project AppTimestamp, Logger, CustomLevel, Thread, Message, ExceptionClass, StackTrace, TraceId, SpanId
    
  4. Dzienniki aplikacji zwracają się, jak pokazano na poniższej ilustracji:

    Screenshot of the Azure portal showing the log Results pane.

Pokaż wpisy dziennika zawierające błędy

Aby przejrzeć wpisy dziennika, które mają błąd, uruchom następujące zapytanie:

AppPlatformLogsforSpring
| where TimeGenerated > ago(1h) and CustomLevel == "ERROR"
| project AppTimestamp, Logger, ExceptionClass, StackTrace, Message, AppName
| sort by AppTimestamp

Użyj tego zapytania, aby znaleźć błędy lub zmodyfikować terminy zapytania, aby znaleźć konkretną klasę wyjątku lub kod błędu.

Pokazywanie wpisów dziennika dla określonego identyfikatora traceId

Aby przejrzeć wpisy dziennika dla określonego identyfikatora śledzenia "trace_id", uruchom następujące zapytanie:

AppPlatformLogsforSpring
| where TimeGenerated > ago(1h)
| where TraceId == "trace_id"
| project AppTimestamp, Logger, TraceId, SpanId, StackTrace, Message, AppName
| sort by AppTimestamp

Następne kroki