Log aplikasi terstruktur untuk Azure Spring Apps

Catatan

Azure Spring Apps adalah nama baru untuk layanan Azure Spring Cloud. Meskipun layanan memiliki nama baru, Anda akan melihat nama lama di beberapa tempat untuk sementara saat kami berupaya memperbarui aset seperti cuplikan layar, video, dan diagram.

Artikel ini berlaku untuk: ✔️ Basic/Standard ✔️ Enterprise

Artikel ini menjelaskan cara menghasilkan dan mengumpulkan data log aplikasi terstruktur di Azure Spring Apps. Dengan konfigurasi yang tepat, Azure Spring Apps menyediakan kueri dan analisis log aplikasi yang berguna melalui Analitik Log.

Persyaratan skema log

Untuk meningkatkan pengalaman kueri log, log aplikasi diperlukan dalam format JSON dan sesuai dengan skema. Azure Spring Apps menggunakan skema ini untuk mengurai aplikasi Anda dan mengalirkan ke Analitik Log.

Catatan

Mengaktifkan format log JSON menjadikan sulit untuk membaca output streaming log dari konsol. Untuk mendapatkan output yang dapat dibaca manusia, tambahkan argumen --format-json ke perintah CLI az spring app logs. Lihat Log terstruktur format JSON.

Persyaratan skema JSON:

Kunci Json Jenis nilai Json Wajib Kolom di Analitik Log Deskripsi
rentang waktu string Ya AppTimestamp tanda waktu dalam format UTC
pencatat string No Pencatat pencatat
tingkat string No CustomLevel tingkat log
rangkaian string No Rangkaian rangkaian
pesan string No Pesan Pesan log
stackTrace string No StackTrace jejak tumpukan pengecualian
exceptionClass string No ExceptionClass nama kelas pengecualian
mdc JSON berlapis No konteks diagnostik yang dipetakan
mdc.traceId string No TraceId lacak ID untuk pelacakan terdistribusi
mdc.spanId string No SpanId ID rentang untuk pelacakan terdistribusi
  • Bidang "tanda waktu" diperlukan, dan harus dalam format UTC, semua bidang lainnya opsional.
  • "traceId" dan "spanId" di bidang "mdc" digunakan untuk tujuan pelacakan.
  • Catat setiap rekaman JSON dalam satu baris.

Sampel rekaman log

{"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"}

Pembatasan

Setiap baris log JSON memiliki paling banyak 16 K byte. Jika output JSON dari rekaman log tunggal melebihi batas ini, output tersebut dipecah menjadi beberapa baris, dan setiap baris mentah dikumpulkan ke dalam Log kolom tanpa diurai secara struktural.

Umumnya, situasi ini terjadi pada pengelogan pengecualian dengan stacktrace mendalam, terutama ketika Agen Dalam Proses AppInsights diaktifkan. Terapkan pengaturan batas pada output stacktrace (lihat sampel konfigurasi di bawah ini) untuk memastikan output akhir diurai dengan benar.

Membuat log JSON yang mematuhi skema

Untuk aplikasi Spring, Anda dapat menghasilkan format log JSON yang diharapkan menggunakan kerangka kerja pengelogan umum, seperti Logback dan Log4j2.

Log dengan logback

Saat menggunakan starter Spring Boot, Logback digunakan secara default. Untuk aplikasi Logback, gunakan logstash-encoder untuk menghasilkan log berformat JSON. Metode ini didukung di Spring Boot versi 2.1 atau yang lebih baru.

Prosedur:

  1. Tambahkan dependensi logstash dalam file pom.xml Anda.

    <dependency>
        <groupId>net.logstash.logback</groupId>
        <artifactId>logstash-logback-encoder</artifactId>
        <version>6.5</version>
    </dependency>
    
  2. Perbarui file konfigurasi logback-spring.xml Anda untuk mengatur 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. Saat menggunakan file konfigurasi pengelogan dengan akhiran -spring seperti logback-spring.xml, Anda dapat mengatur konfigurasi pengelogan berdasarkan profil aktif 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>
    

    Untuk pengembangan lokal, jalankan aplikasi Spring dengan argumen JVM -Dspring.profiles.active=dev, Anda dapat melihat log yang dapat dibaca manusia dan bukan garis yang diformat JSON.

Log dengan log4j2

Untuk aplikasi log4j2, gunakan json-template-layout untuk membuat log berformat JSON. Metode ini didukung di Spring Boot versi 2.1+.

Prosedur:

  1. Kecualikan spring-boot-starter-logging dari spring-boot-starter, tambahkan dependensi spring-boot-starter-log4j2, log4j-layout-template-json dalam file pom.xml Anda.

    <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. Siapkan file templat tata letak JSON jsonTemplate.json di jalur kelas Anda.

    {
        "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. Gunakan templat tata letak JSON ini dalam file konfigurasi log4j2-spring.xml.

    <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>
    

Menganalisis log di Analitik Log

Setelah aplikasi Anda disiapkan dengan benar, log konsol aplikasi Anda dialirkan ke Analitik Log. Struktur ini mengaktifkan kueri yang efisien di Analitik Log.

Periksa struktur log di Analitik Log

Gunakan prosedur berikut:

  1. Buka halaman gambaran umum layanan instans layanan Anda.

  2. Pilih entri Log di bagian Pemantauan.

  3. Jalankan kueri ini.

    AppPlatformLogsforSpring
    | where TimeGenerated > ago(1h)
    | project AppTimestamp, Logger, CustomLevel, Thread, Message, ExceptionClass, StackTrace, TraceId, SpanId
    
  4. Log aplikasi muncul seperti yang ditunjukkan pada gambar berikut:

    Screenshot of the Azure portal showing the log Results pane.

Perlihatkan entri log yang berisi kesalahan

Untuk meninjau entri log yang mengalami kesalahan, jalankan kueri berikut:

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

Gunakan kueri ini untuk menemukan kesalahan, atau ubah istilah kueri untuk menemukan kelas pengecualian atau kode kesalahan tertentu.

Perlihatkan entri log untuk traceId tertentu

Untuk meninjau entri log untuk ID pelacakan khusus "trace_id", jalankan kueri berikut:

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

Langkah berikutnya