티스토리 뷰

golang

Concurrent Logging - in Golang

fistful 2019. 6. 17. 13:33
반응형

개요

 

go routine 이용해서 프로그램의 여기저기서 하나의 파일에 write 한다면 어떻게 될까?

go routine 충돌을 하지 않을거란 보증은 하지 않는다.

 

참고 링크

- Golang Package os: https://golang.org/pkg/os

- Golang Package log: https://golang.org/pkg/log

- log for concurrency: https://codereview.stackexchange.com/a/209872

 

해법

 

하나의 리소스에 동시에 여럿이 접근하려 할때 충돌을 막는 방법을 생각하면 바로 mutex 떠오를 것이다.

 

1) A 접근하면서 mutex lock 걸어놓는다. 그러면 다른 녀석이 접근 권한을 가지지 못한다.

2) A 사용 완료후 mutex unlock 으로 해제하면 다른 녀석이 접근할 있다.

 

여기서는 여러 go routine 에서 하나의 log 파일에 write 하려하는데 mutex 같은 동시접근을 막아주는 녀석이 필요해진다.

경우엔 그냥 golang log package 쓰면 된다.

 

해법 - 예제 프로그램

 

예제 프로그램 부터 돌려보자.

GitHub Gist: https://gist.github.com/nicewook/8ab51cc920b242f3fed6d560dd790afa

1) os.OpenFile() 파일을 엽니다.

- os.O_CREATE: 없다면 생성됨

- os.O_APPEND: 있다면 기존 내용에 이어져서 써짐

- os.O+WRONLY: 쓰기만 가능합니다.

 

2) log.New() 함수로 type Logger 생성하고 포인터를 fileLogger 저장

 

3) wait.Add() 해두면

- wait.Done() 개수만큼 호출될때까지

- wait.Wait() 에서 기다림

 

4) for loop 통해 100개의 go routine 만들어 실행

- 현재 시간을 string 으로 변환하여

- 현재 go routine 번호와 함께 log 출력하고

- 파일에 저장한다.

 

프로그램을 go run main.go 돌려보면

concurrent_log.log 파일이 생성되며 log 찍힌 것을 확인할 있다.

그런데 그냥 File.WriteSting() 사용해도 문제는 없었다.

하지만 문제가 생길 가능성이 있는 것이다.

 

 

 

 

참고. log. New() 파라미터들

 

func New(out io.Writer, prefix string, flag int) *Logger

 

코드에서는 log.New(f, "", 0) 주었다.

- f io.Writer Open file 전달한

- prefix 따로 적을 것이 없으므로 "", 만약 log 라면 time.Now() 현재 시간을 얻은 넣어줘도 같다.

- flag 아래 항목들을 | (OR 연산자)로 묶어 지정할 수 있다. 여기서는 아무것도 주지 않았음

표준플래그(log.LstdFlags)

날짜플래그(log.Ldate)

시간플래그(log.Ltime)

파일위치플래그(log.Lshortfile, log.Llongfile)

 

참고. Logger.Output mutex

 

- 링크: https://golang.org/src/log/log.go?s=5252:5306#L139

 

 

runtime.Caller(calldepth) 뭘까?

 

링크: https://ispycode.com/GO/Logging/Output-with-Calldepth

GitHub Gist: https://gist.github.com/nicewook/2e9209b0d59a0bc00970179e636d590d

 

Call stack 관련이라 보면 되겠다. 호출한 함수1 호출하는 함수2 호출하는 함수3에서 log.Output() 호출했다면

아래 링크와 같이 호출한 파일의 함수 위치가 출력된다.

* log.New() 시에 log.Llogfile 플래그를 넣었다.

 


반응형

'golang' 카테고리의 다른 글

Golang 개발시 Makefile 사용해보기  (0) 2019.06.24
Maximum Subarray Problem  (0) 2019.06.19
Concurrent Logging - in Golang  (0) 2019.06.17
gRPC - Go Quick Start  (1) 2019.06.10
Protocol Buffers - Golang Tutorial  (0) 2019.06.07
Protocol Buffers - overview  (1) 2019.06.06
댓글
댓글쓰기 폼