빅토리 코딩
article thumbnail
728x90
반응형

5. springboot

새로만들기 귀찮다면 내가 올린 테스트 사용~!

https://github.com/victory940209/testspringboot/tree/main/testSpringboot

 

GitHub - victory940209/testspringboot

Contribute to victory940209/testspringboot development by creating an account on GitHub.

github.com

 

 

1. pom.xml 설정

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.7.8</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

...
	<properties>
		<java.version>11</java.version>
		<spring-cloud.version>3.1.5</spring-cloud.version>
	</properties>
...
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-sleuth</artifactId>
			<version>${spring-cloud.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-sleuth-zipkin</artifactId>
			<version>${spring-cloud.version}</version>
		</dependency>
		<dependency>
			<groupId>io.micrometer</groupId>
			<artifactId>micrometer-core</artifactId>
		</dependency>
		<dependency>
			<groupId>io.micrometer</groupId>
			<artifactId>micrometer-tracing-bridge-brave</artifactId>
			<version>1.0.1</version>
		</dependency>
		<dependency>
			<groupId>io.zipkin.brave</groupId>
			<artifactId>brave-instrumentation-http</artifactId>
			<version>5.13.3</version>
		</dependency>
		<dependency>
			<groupId>io.zipkin.brave</groupId>
			<artifactId>brave</artifactId>
			<version>5.13.3</version>
		</dependency>
		<dependency>
			<groupId>io.zipkin.reporter2</groupId>
			<artifactId>zipkin-reporter-brave</artifactId>
			<version>2.16.3</version>
		</dependency>
        <!-- 로그를 Loki로 바로 보내려면 설정 필요 -->
		<dependency>
			<groupId>com.github.loki4j</groupId>
			<artifactId>loki-logback-appender</artifactId>
			<version>1.4.0-m1</version>
		</dependency>

...
처음에 spring boot 3으로 해보려고 할때  sleuth가 spring boot3에서 지원을 하지않았다.....그래서 io.micrometer와 io.zipkin를 사용해서 했는데 회사에서 버전을 낮추자고 해서...... sleuth가 다시 추가.... 정리를 한번 하고 다시 올리겠다.

 

2.application.yml 설정

server:
  port: 9000

spring:
  application:
    name: springboot01
  pid:
    file: /data1/springboot/springboot01.pid
  zipkin:
    base-url: http://127.0.0.1:9411  #zipkin 연결 부분 ip.port

logging:
  config: classpath:logback-local.xml  #logback 파일 위치 설정

3. logback설정 (Loki에 데이터를 바로 보내는 설정)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE xml>
<configuration debug="false" scan="true"
	scanPeriod="30 seconds">

	<property name="LOGS_PATH" value="/data/logs" />
	<springProperty scope="context" name="appName" source="spring.application.name"/>

	<appender name="log_file"
		class="ch.qos.logback.core.rolling.RollingFileAppender">
		<file>${LOGS_PATH}/springboot01.log</file>

		<encoder
			class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) %magenta(%-4relative) --- [${appName} ,%blue(%X{traceId}), %green(%X{spanId})] %cyan(%logger{20}) : %msg%n</pattern>
		</encoder>
		<rollingPolicy
			class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			<fileNamePattern>${LOGS_PATH}/springboot01_%d{yyyyMMdd}.log</fileNamePattern>
			<maxHistory>60</maxHistory>
		</rollingPolicy>
	</appender>
	<logger name="com.victory" level="DEBUG">
		<appender-ref ref="log_file" />
	</logger>

	<appender name="console"
		class="ch.qos.logback.core.ConsoleAppender">
		<layout class="ch.qos.logback.classic.PatternLayout">
			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) %magenta(%-4relative) --- [${appName}, %blue(%X{traceId}), %green(%X{spanId}) %X{sessionId}] %cyan(%logger{20}) : %msg%n</pattern>
		</layout>
	</appender>

	 <appender name="LOKI" class="com.github.loki4j.logback.Loki4jAppender">
        <http>
            <url>http://192.168.0.103:3200/loki/api/v1/push</url>
        </http>
        <format>
            <label>
                <pattern>app=${appName},host=${HOSTNAME},traceID=%X{traceId:-NONE},level=%level</pattern>
            </label>
            <message>
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) %magenta(%-4relative) --- [${appName}, %blue(%X{traceId}), %green(%X{spanId})] %cyan(%logger{20}) : %msg%n</pattern>
            </message>
            <sortByTime>true</sortByTime>
        </format>
    </appender>


	<root level="DEBUG">
		<appender-ref ref="console" />
		<appender-ref ref="log_file" />
		<appender-ref ref="LOKI" />
	</root>

	<logger name="com.victory" level="DEBUG" additivity="false">
		<appender-ref ref="console" />
		<appender-ref ref="log_file" />
		<appender-ref ref="LOKI" />

	</logger>
</configuration>

여기서 중요한점은

<property name="LOGS_PATH" value="/data/logs" />

-> promtail에서 설정한 위치

 

<file>${LOGS_PATH}/springboot01.log</file>

-> promtail에서 설정한 이름


<springProperty scope="context" name="appName" source="spring.application.name"/>

->application.yml에서 설정한 spring.application.name을 appName변수에 담은것

 

<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) %magenta(%-4relative) --- [${appName} ,%blue(%X{traceId}), %green(%X{spanId})] %cyan(%logger{20}) : %msg%n</pattern>

-> 로그 패턴안에 appName, traceId, spanId를 넣어다는것

 

4. java 설정(log tracing 처리)

 Config 생성 http 통신을 할때 RestTemplate를 이용하여 하는데 해당 을 관찰하기 위해서 import io.micrometer.observation 설정

import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

import io.micrometer.observation.ObservationRegistry;
import io.micrometer.observation.aop.ObservedAspect;

@Configuration(proxyBeanMethods = false)
public class MyConfiguration {
	
    @Bean
    RestTemplate restTemplate(RestTemplateBuilder builder) {
        return builder.build();
    }
	
    @Bean
    ObservedAspect observedAspect(ObservationRegistry observationRegistry) {
        return new ObservedAspect(observationRegistry);
    }
    
    
    @Bean
    ObservationRegistry observationRegistry() {
        return ObservationRegistry.create();
    }

}

 

Controller를 생성

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.client.RestTemplate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import io.micrometer.observation.Observation;
import io.micrometer.observation.ObservationRegistry;

@Slf4j
@RestController
public class TestController {
	@Autowired
	private ObservationRegistry observationRegistry;

	@Autowired
	RestTemplate restTemplate;


	@GetMapping(value = "/test", produces = MediaType.APPLICATION_JSON_VALUE)
	public Map<String, Object> test(@RequestParam Map<String, Object> param) throws Exception {

		log.debug("param : {}", param);

		return Map.of("key1", "value1", "key2", "value2");

	}

	@PostMapping(value = "/testResultPost")
	public Map<String, Object> testResultVoPost(@RequestBody Map<String, Object> param) throws Exception {

		String url = param.get("url").toString();
		String port = param.get("port").toString();
		String resulturl = "http://127.0.0.1:" + port + "/" + url;

		Observation.createNotStarted("user.name", observationRegistry)
				.contextualName("httpGetConnection")
				.lowCardinalityKeyValue(url, url)
				.observe(() -> {

		ResponseEntity respEntity = restTemplate.getForEntity(resulturl, Map.class);

		log.info("result : {}", respEntity.getBody());

		});

		return Map.of("key12345", "value12345", "key2", "value2");
	}
    
    ...
 }

 

5. 실행

 

로그내용에 logback 설정 하였던 appName, traceId, spanId 3개가 나오는것을 알수 있다.

zipkin 화면

grafana화면

성공! 이제 springboot01에서 springboot02를 호출 할때 로그 트레이싱이 잘되는지 확인해볼것이다.!

728x90
반응형
profile

빅토리 코딩

@빅토리 코딩

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

검색 태그