ใญใฐใ Datadog ใซ้ไฟกใใใซใฏใใใกใคใซใซใญใฐใ่จ้ฒใใใใฎใใกใคใซใ Datadog Agent ใง tail ใใพใใ
ไธ่ฌ็ใช Java ใญใฐใฎในใฟใใฏใใฌใผในใฏ่คๆฐใฎ่กใซๅๅฒใใใฆใใใใใๅ
ใฎใญใฐใคใใณใใซ้ข้ฃไปใใใใจใๅฐ้ฃใงใใไพ:
//1 ใคใฎใฏใใฎใคใใณใใซใ4 ใคใฎใคใใณใใ็ๆใใใ
Exception in thread "main" java . lang . NullPointerException
at com . example . myproject . Book . getTitle ( Book . java : 16 )
at com . example . myproject . Author . getBookTitles ( Author . java : 25 )
at com . example . myproject . Bootstrap . main ( Bootstrap . java : 14 )
ใใฎๅ้กใ่งฃๆฑบใใใซใฏใใญใฐใ JSON ๅฝขๅผใง็ๆใใใใใซใญใฐใฉใคใใฉใชใๆงๆใใพใใJSON ใซใญใฐใใใจใๆฌกใฎใใจใใงใใพใใ
ในใฟใใฏใใฌใผในใใญใฐใคใใณใใซ้ฉๅใซใฉใใใใใใใจใ็ขบๅฎใซใใพใใ ใในใฆใฎใญใฐใคใใณใๅฑๆง (้ๅคงๅบฆใใญใฌใผๅใในใฌใใๅใชใฉ) ใ้ฉๅใซๆฝๅบใใใใใจใ็ขบๅฎใซใใพใใ ใใใใใใ่จบๆญใณใณใใญในใ (MDC) ๅฑๆงใซใขใฏใปในใงใใพใใใใฎๅฑๆงใฏใไปปๆใฎใญใฐใคใใณใใซใขใฟใใใงใใพใใใซในใฟใ ใใผในใซใผใซ ใไธ่ฆใซใชใใพใใๆฌกใฎๆ้ ใฏใLog4jใLog4j 2ใใใใณ Logback ใญใฐใฉใคใใฉใชใฎใปใใใขใใไพใ็คบใใฆใใพใใ
ใญใฌใผใฎๆงๆ JSON ๅฝขๅผ Log4j ใฎๅ ดๅใSLF4J ใขใธใฅใผใซ log4j-over-slf4j ใ Logback ใจ็ตใฟๅใใใฆไฝฟ็จใใฆ JSON ๅฝขๅผใงใญใฐใใพใใlog4j-over-slf4j
ใฏใใขใใชใฑใผใทใงใณใฎ Log4j ใๅฎๅ
จใซ็ฝฎใๆใใใใใใณใผใใๅคๆดใใๅฟ
่ฆใฏใใใพใใใ
pom.xml
ใใกใคใซใงใlog4j.jar
ไพๅญ้ขไฟใ log4j-over-slf4j.jar
ไพๅญ้ขไฟใซ็ฝฎใๆใใLogback ไพๅญ้ขไฟใ่ฟฝๅ ใใพใใไพ:
<dependency>
<groupId> org.slf4j</groupId>
<artifactId> log4j-over-slf4j</artifactId>
<version> 1.7.32</version>
</dependency>
<dependency>
<groupId> ch.qos.logback</groupId>
<artifactId> logback-classic</artifactId>
<version> 1.2.9</version>
</dependency>
<dependency>
<groupId> net.logstash.logback</groupId>
<artifactId> logstash-logback-encoder</artifactId>
<version> 6.6</version>
</dependency>
logback.xml
ใง JSON ใฌใคใขใฆใใไฝฟ็จใใใขใใณใใผใๆงๆใใฆใใ ใใใใใกใคใซใจใณใณใฝใผใซๅใใฎใตใณใใซๆงๆใฏไปฅไธใๅ็
งใใฆใใ ใใใ
ใใกใคใซ:
<configuration>
<appender name= "FILE" class= "ch.qos.logback.core.FileAppender" >
<file> logs/app.log</file>
<encoder class= "net.logstash.logback.encoder.LogstashEncoder" />
</appender>
<root level= "INFO" >
<appender-ref ref= "FILE" />
</root>
</configuration>
ใณใณใฝใผใซ:
<configuration>
<appender name= "CONSOLE" class= "ch.qos.logback.core.ConsoleAppender" >
<encoder class= "ch.qos.logback.classic.encoder.JsonEncoder" />
</appender>
<root>
<level value= "DEBUG" />
<appender-ref ref= "CONSOLE" />
</root>
</configuration>
Log4j 2 ใซใฏ JSON ใฌใคใขใฆใใๅซใพใใฆใใพใใ
log4j2.xml
ใง JSON ใฌใคใขใฆใใไฝฟ็จใใใขใใณใใผใๆงๆใใฆใใ ใใใใใกใคใซใใใณใณใณใฝใผใซใขใใณใใผๅใใฎใตใณใใซๆงๆใฏไปฅไธใๅ็
งใใฆใใ ใใใLog4j ใใฉใฐใคใณใฎใใ่ฉณ็ดฐใช่ชฌๆใซใคใใฆใฏใLog4j Plugin ใชใใกใฌใณใน ใใ่ฆงใใ ใใใCopy
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<File name= "FILE" fileName= "logs/app.log" >
<JsonTemplateLayout eventTemplateUri= "classpath:MyLayout.json" />
</File>
</Appenders>
<Loggers>
<Root level= "INFO" >
<AppenderRef ref= "FILE" />
</Root>
</Loggers>
</Configuration>
Copy
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Console name= "console" target= "SYSTEM_OUT" >
<JsonTemplateLayout eventTemplateUri= "classpath:MyLayout.json" />
</Console>
</Appenders>
<Loggers>
<Root level= "INFO" >
<AppenderRef ref= "console" />
</Root>
</Loggers>
</Configuration>
JSON ใฌใคใขใฆใใฎไพๅญ้ขไฟใ pom.xml
ใซ่ฟฝๅ ใใพใใไพ:<dependency>
<groupId> org.apache.logging.log4j</groupId>
<artifactId> log4j-core</artifactId>
<version> 2.17.1</version>
</dependency>
<dependency>
<groupId> com.fasterxml.jackson.core</groupId>
<artifactId> jackson-core</artifactId>
<version> 2.13.0</version>
</dependency>
<dependency>
<groupId> com.fasterxml.jackson.core</groupId>
<artifactId> jackson-databind</artifactId>
<version> 2.13.0</version>
</dependency>
<dependency>
<groupId> com.fasterxml.jackson.core</groupId>
<artifactId> jackson-annotations</artifactId>
<version> 2.13.0</version>
</dependency>
Logback ใฎ JSON ๅฝขๅผใฎใญใฐใซใฏใlogstash-logback-encoder ใไฝฟ็จใใพใใ
logback.xml
ใฎ JSON ใฌใคใขใฆใใไฝฟ็จใใฆใใกใคใซใขใใณใใผใๆงๆใใพใใไพ:
<configuration>
<appender name= "FILE" class= "ch.qos.logback.core.FileAppender" >
<file> logs/app.log</file>
<encoder class= "net.logstash.logback.encoder.LogstashEncoder" />
</appender>
<root level= "INFO" >
<appender-ref ref= "FILE" />
</root>
</configuration>
Logstash ใจใณใณใผใใฎไพๅญ้ขไฟใ pom.xml
ใใกใคใซใซ่ฟฝๅ ใใพใใไพ:
<dependency>
<groupId> ch.qos.logback</groupId>
<artifactId> logback-classic</artifactId>
<version> 1.2.9</version>
</dependency>
<dependency>
<groupId> net.logstash.logback</groupId>
<artifactId> logstash-logback-encoder</artifactId>
<version> 6.6</version>
</dependency>
Tinylog ๅ
ฌๅผใใญใฅใกใณใ ใซๅบใฅใใฆใJSON ใฉใคใฟใผใฎๆงๆใไฝๆใใพใใ
tinylog.properties
ใใกใคใซใงใฏๆฌกใฎๅฝขๅผใไฝฟ็จใใฆใใ ใใใ
writer = json
writer.file = log.json
writer.format = LDJSON
writer.level = info
writer.field.level = level
writer.field.source = {class}.{method}()
writer.field.message = {message}
writer.field.dd.trace_id = {context: dd.trace_id}
writer.field.dd.span_id = {context: dd.span_id}
writer.field.dd.service = {context: dd.service}
writer.field.dd.version = {context: dd.version}
writer.field.dd.env = {context: dd.env}
ใญใฐใธใฎใใฌใผใน ID ใฎๆฟๅ
ฅ ใใฎใขใใชใฑใผใทใงใณใง APM ใๆๅนใซใชใฃใฆใใๅ ดๅใฏใใใฌใผใน ID ใคใณใธใงใฏใทใงใณใๆๅนใซใใใใจใงใใญใฐใจใใฌใผในใ็ธไบใซ้ข้ฃไปใใใใจใใงใใพใใ่ฉณ็ดฐใซใคใใฆใฏใJava ใญใฐใจใใฌใผในใฎๆฅ็ถ ใๅ็
งใใฆใใ ใใใ
ๆชๅ ๅทฅใฎๅฝขๅผ log4j.xml
ใงใใกใคใซใขใใณใใผใๆงๆใใพใใไพ:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>
<appender name= "FILE" class= "org.apache.log4j.FileAppender" >
<param name= "File" value= "logs/app.log" />
<param name= "Append" value= "true" />
<layout class= "org.apache.log4j.PatternLayout" >
<param name= "ConversionPattern" value= "%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %X{dd.trace_id} %X{dd.span_id} - %m%n" />
</layout>
</appender>
<root>
<priority value= "INFO" />
<appender-ref ref= "FILE" />
</root>
</log4j:configuration>
log4j2.xml
ใงใใกใคใซใขใใณใใผใๆงๆใใพใใไพ:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<File name= "FILE" fileName= "logs/app.log" >
<PatternLayout pattern= "%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %X{dd.trace_id} %X{dd.span_id} - %m%n" />
</File>
</Appenders>
<Loggers>
<Root level= "INFO" >
<AppenderRef ref= "FILE" />
</Root>
</Loggers>
</Configuration>
logback.xml
ใงใใกใคใซใขใใณใใผใๆงๆใใพใใไพ:
<configuration>
<appender name= "FILE" class= "ch.qos.logback.core.FileAppender" >
<file> ${dd.test.logfile}</file>
<append> false</append>
<immediateFlush> true</immediateFlush>
<encoder>
<pattern> %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %X{dd.trace_id} %X{dd.span_id} - %m%n</pattern>
</encoder>
</appender>
<root level= "INFO" >
<appender-ref ref= "FILE" />
</root>
</configuration>
ๅ
ฌๅผ Tinylog ใใญใฅใกใณใ ใซๅบใฅใใใใกใคใซใธๅบๅใใใใใฎใฉใคใฟใผๆงๆใไฝๆใใฆใใ ใใใ
tinylog.properties
ใใกใคใซใงใฏไปฅไธใฎๅฝขๅผใไฝฟ็จใใฆใใ ใใใ
writer = file
writer.level = debug
writer.format = {level} - {message} - "dd.trace_id":{context: dd.trace_id} - "dd.span_id":{context: dd.span_id}
writer.file = log.txt
ใญใฐใธใฎใใฌใผใน ID ใฎๆฟๅ
ฅ ใใฎใขใใชใฑใผใทใงใณใง APM ใๆๅนใซใชใฃใฆใใๅ ดๅใฏใใใฌใผใน ID ใคใณใธใงใฏใทใงใณใๆๅนใซใใใใจใงใใญใฐใจใใฌใผในใ็ธไบใซ้ข้ฃไปใใใใจใใงใใพใใJava ใญใฐใจใใฌใผในใฎๆฅ็ถ ใๅ็
งใใฆใใ ใใใ
ใญใฐใจใใฌใผในใ็ธ้ขใใใฆใใชใๅ ดๅใฏใไธ่จใฎๆงๆไพใซๅซใพใใฆใใใญใฐใใฟใผใณใใ MDC ใใฌใผในใใซใใผ (%X{dd.trace_id} %X{dd.span_id}
) ใๅ้คใงใใพใใ
Datadog Agent ใฎๆงๆ ใญใฐๅ้ใๆๅน ใซใชใฃใใใใญใฐใใกใคใซใ่ฟฝ่ทกใใฆ Datadog ใซ้ไฟกใใใซในใฟใ ใญใฐๅ้ ใ่จญๅฎใใพใใ
java.d/
ใใฉใซใใผใ conf.d/
Agent ๆงๆใใฃใฌใฏใใช ใซไฝๆใใพใใ
java.d/
ใซไปฅไธใฎๅ
ๅฎนใง conf.yaml
ใใกใคใซใไฝๆใใพใใ
#Log section
logs :
- type : file
path : "<path_to_your_java_log>.log"
service : <service_name>
source : java
sourcecategory : sourcecode
# For multiline logs, if they start by the date with the format yyyy-mm-dd uncomment the following processing rule
#log_processing_rules:
# - type: multi_line
# name: new_log_start_with_date
# pattern: \d{4}\-(0?[1-9]|1[012])\-(0?[1-9]|[12][0-9]|3[01])
Agent ใๅ่ตทๅใใพใ ใ
Agent ใฎ status ใตใใณใใณใ ใๅฎ่กใใChecks
ใปใฏใทใงใณใง java
ใๆขใใใญใฐใ Datadog ใซๆญฃๅธธใซ้ไฟกใใใใใจใ็ขบ่ชใใพใใ
ใญใฐใ JSON ๅฝขๅผใฎๅ ดๅใDatadog ใฏ่ชๅ็ใซใญใฐใกใใปใผใธใใใผใน ใใใญใฐๅฑๆงใๆฝๅบใใพใใใญใฐใจใฏในใใญใผใฉใผ ใไฝฟ็จใใฆใใญใฐใ่กจ็คบใใใใฉใใซใทใฅใผใใฃใณใฐใ่กใใใจใใงใใพใใ
ใจใผใธใงใณใใฌในใฎใญใฐๅ้ ใขใฏใปในใงใใชใใใพใใฏใใกใคใซใซใญใฐใ่จ้ฒใงใใชใใใทใณใงใขใใชใฑใผใทใงใณใๅฎ่กใใใฆใใไพๅค็ใชใฑใผในใงใฏใใญใฐใ Datadog ใพใใฏ Datadog Agent ใซ็ดๆฅในใใชใผใใณใฐใใใใจใใงใใพใใใขใใชใฑใผใทใงใณใๆฅ็ถใฎๅ้กใๅฆ็ใใๅฟ
่ฆใใใใใใใใใฏๆจๅฅจใใใ่จญๅฎใงใฏใใใพใใใ
ใญใฐใ Datadog ใซ็ดๆฅในใใชใผใใณใฐใใใซใฏ
Logback ใญใฐใฉใคใใฉใชใใณใผใใซ่ฟฝๅ ใใใใ็พๅจใฎใญใฌใผใ Logback ใซใใชใใธ ใใพใใ Logback ใๆงๆ ใใฆ Datadog ใซใญใฐใ้ไฟกใใพใใJava ใญใฎใณใฐใฉใคใใฉใชใใ Logback ใธใฎใใชใใธ ใพใ Logback ใไฝฟ็จใใฆใใชใๅ ดๅใใปใจใใฉใฎไธ่ฌ็ใชใญใฐใฉใคใใฉใชใฏ Logback ใซใใชใใธใใใใจใใงใใพใใ
SLF4J ใขใธใฅใผใซ log4j-over-slf4j ใ Logback ใจใจใใซไฝฟ็จใใฆใใญใฐใๅฅใฎใตใผใใผใซ้ไฟกใใพใใlog4j-over-slf4j
ใฏใใขใใชใฑใผใทใงใณใฎ Log4j ใๅฎๅ
จใซ็ฝฎใๆใใใใใใณใผใใๅคๆดใใๅฟ
่ฆใฏใใใพใใใ
pom.xml
ใใกใคใซใงใlog4j.jar
ไพๅญ้ขไฟใ log4j-over-slf4j.jar
ไพๅญ้ขไฟใซ็ฝฎใๆใใLogback ไพๅญ้ขไฟใ่ฟฝๅ ใใพใใไพ:<dependency>
<groupId> org.slf4j</groupId>
<artifactId> log4j-over-slf4j</artifactId>
<version> 1.7.32</version>
</dependency>
<dependency>
<groupId> ch.qos.logback</groupId>
<artifactId> logback-classic</artifactId>
<version> 1.2.9</version>
</dependency>
<dependency>
<groupId> net.logstash.logback</groupId>
<artifactId> logstash-logback-encoder</artifactId>
<version> 6.6</version>
</dependency>
Logback ใๆงๆใใพใใ ๆณจ: ใใฎๅคๆดใฎ็ตๆใLog4j ใณใณใใฃใฎใฅใฌใผใทใงใณใใกใคใซใฏไฝฟ็จใใใชใใชใใพใใLog4j ใใฉใณในใฌใผใฟใผ ใไฝฟ็จใใฆ log4j.properties
ใใกใคใซใ logback.xml
ใซ็งป่กใใฆใใ ใใใ
Log4j 2 ใงใฏใใชใขใผใใในใใธใฎใญใฐ่จ้ฒใๅฏ่ฝใงใใใใญใฐใฎๅใซ API ใญใผใไปใใๆฉ่ฝใฏใใใพใใใใใฎใใใSLF4J ใขใธใฅใผใซ log4j-over-slf4j ใจ Logback ใไฝฟ็จใใฆใใ ใใใlog4j-to-slf4j.jar
ใฏใใขใใชใฑใผใทใงใณใฎ Log4j 2 ใๅฎๅ
จใซ็ฝฎใๆใใใใใใณใผใใๅคๆดใใๅฟ
่ฆใฏใใใพใใใใใใไฝฟ็จใใใซใฏ
pom.xml
ใใกใคใซใงใlog4j.jar
ไพๅญ้ขไฟใ log4j-over-slf4j.jar
ไพๅญ้ขไฟใซ็ฝฎใๆใใLogback ไพๅญ้ขไฟใ่ฟฝๅ ใใพใใไพ:<dependency>
<groupId> org.apache.logging.log4j</groupId>
<artifactId> log4j-to-slf4j</artifactId>
<version> 2.17.1</version>
</dependency>
<dependency>
<groupId> ch.qos.logback</groupId>
<artifactId> logback-classic</artifactId>
<version> 1.2.9</version>
</dependency>
<dependency>
<groupId> net.logstash.logback</groupId>
<artifactId> logstash-logback-encoder</artifactId>
<version> 6.6</version>
</dependency>
Logback ใๆงๆใใพใใ ๆณจ:
Logback ใๆงๆใใ
logstash-logback-encoder ใญใฐใฉใคใใฉใชใ Logback ใจไธ็ทใซไฝฟ็จใใฆใใญใฐใ Datadog ใซ็ดๆฅในใใชใผใใณใฐใใพใใ
logback.xml
ใใกใคใซใซ TCP ใขใใณใใผใๆงๆใใพใใใใฎๆงๆใงใฏใAPI ใญใผใฏ็ฐๅขๅคๆฐ DD_API_KEY
ใใๅๅพใใใพใใใใใใฏใใณใณใใฃใฎใฅใฌใผใทใงใณใใกใคใซใซ็ดๆฅ API ใญใผใๆฟๅ
ฅใใใใจใใงใใพใใ
ไปฅไธใฎๆงๆใไฝฟ็จใใ้ใฏใ<YOUR REGION INTAKE>
ใใๅฉ็จใฎๅฐๅใซๅฟใใใคใณใใผใฏ (
) ใซ็ฝฎใๆใใฆใใ ใใใ
US1 : intake.logs.datadoghq.com:10516
EU : tcp-intake.logs.datadoghq.eu:443
<configuration>
<appender name= "FILE" class= "ch.qos.logback.core.FileAppender" >
<file> logs/app.log</file>
<encoder class= "net.logstash.logback.encoder.LogstashEncoder" />
</appender>
<appender name= "JSON_TCP" class= "net.logstash.logback.appender.LogstashTcpSocketAppender" >
<destination><YOUR REGION INTAKE ></destination>
<keepAliveDuration> 20 seconds</keepAliveDuration>
<encoder class= "net.logstash.logback.encoder.LogstashEncoder" >
<prefix class= "ch.qos.logback.core.encoder.LayoutWrappingEncoder" >
<layout class= "ch.qos.logback.classic.PatternLayout" >
<pattern> ${DD_API_KEY} %mdc{keyThatDoesNotExist}</pattern>
</layout>
</prefix>
</encoder>
<ssl />
</appender>
<root level= "DEBUG" >
<appender-ref ref= "FILE" />
<appender-ref ref= "JSON_TCP" />
</root>
</configuration>
ๆณจ: XML ใณใณใใฃใฎใฅใฌใผใทใงใณใง็ฉบ็ฝใๅ้คใใใใใใ%mdc{keyThatDoesNotExist}
ใ่ฟฝๅ ใใใพใใใใฌใใฃใใฏในใใฉใกใผใฟใฎ่ฉณ็ดฐใซใคใใฆใฏใLogback ใใญใฅใกใณใ ใๅ็
งใใฆใใ ใใใ
Logstash ใจใณใณใผใใฎไพๅญ้ขไฟใ pom.xml
ใใกใคใซใซ่ฟฝๅ ใใพใใไพ:
<dependency>
<groupId> ch.qos.logback</groupId>
<artifactId> logback-classic</artifactId>
<version> 1.2.9</version>
</dependency>
<dependency>
<groupId> net.logstash.logback</groupId>
<artifactId> logstash-logback-encoder</artifactId>
<version> 6.6</version>
</dependency>
่ฃ่ถณ่ชฌๆ ใญใฐใคใใณใใใณใณใใญในใๅฑๆงใง่ฃๅฎใใใใจใใงใใพใใ
ใญใผๅคใใผใตใผใฎไฝฟ็จ ใญใผๅคใใผใตใผ ใฏใใญใฐใคใใณใๅ
ใง่ช่ญใใใ <KEY>=<VALUE>
ใใฟใผใณใๆฝๅบใใพใใ
Java ใฎใญใฐใคใใณใใ่ฃๅฎใใใซใฏใใณใผใใงใกใใปใผใธใๆธใ็ดใใ<ใญใผ>=<ๅค>
ใฎใทใผใฑใณในใๆฟๅ
ฅใใพใใ
ใใจใใฐใๆฌกใฎใกใใปใผใธใใใใจใใพใใ
logger . info ( "Emitted 1001 messages during the last 93 seconds for customer scope prod30" );
ใใใๆฌกใฎใใใซๅคๆดใใพใใ
logger . info ( "Emitted quantity=1001 messages during the last durationInMs=93180 ms for customer scope=prod30" );
ใญใผๅคใใผใตใผใๆๅนใซใใใจใๅใใขใ JSON ใใๆฝๅบใใใพใใ
{
"message" : "Emitted quantity=1001 messages during the last durationInMs=93180 ms for customer scope=prod30" ,
"scope" : "prod30" ,
"durationInMs" : 93180 ,
"quantity" : 1001
}
ใใใงใscope ใใใฃใผใซใใdurationInMs ใจ quantity ใใญใฐใกใธใฃใผใจใใฆๅฉ็จใงใใพใใ
MDC ใญใฐใ่ฃๅฎใใใใ 1 ใคใฎๆนๆณใจใใฆใJava ใฎ ใใใใใใ่จบๆญใณใณใใญในใ (MDC) ใฎๅฉ็จใใใใพใใ
SLF4J ใไฝฟ็จใใๅ ดๅใฏใๆฌกใฎ Java ใณใผใใไฝฟ็จใใฆใใ ใใใ
...
MDC . put ( "scope" , "prod30" );
logger . info ( "Emitted 1001 messages during the last 93 seconds" );
...
ใใฎ JSON ใ็ๆใใใซใฏ
{
"message" : "้ๅป 93 ็ง้ใซ 1001 ใกใใปใผใธใ้ไฟก" ,
"scope" : "prod30"
}
ๆณจ : MDC ใฏๆๅญๅใฟใคใใฎใฟใ่จฑๅฏใใใใใๆฐๅคใกใใชใฏในใซใฏไฝฟ็จใใชใใงใใ ใใใ
ใใฎไปใฎๅ่่ณๆ ใๅฝนใซ็ซใคใใญใฅใกใณใใใชใณใฏใ่จไบ: