본문으로 바로가기
728x90
반응형
728x170

log수집 서버에서 invalid character '\x00' in string literal라는 에러가 빈번하게 발생하여 원인을 찾아보니 

r.body에서 읽어오는 값의 크기가 특정 크기보다 커지면 저 에러를 발생시킨 것입니다.

그래서 JSON Data가 짤리게 출력 되는 모습을 보여주어서 현재 보다 더 많은 Data를 받아 올 수 있도록 수정해 주어야 했습니다.

 

먼저 얼마만큼의 데이터를 받아 오는지 확인하기 위해 length값을 조회했더니 저 에러가 나지 않는 범위가 length값이 3836이였을 때 였습니다.

그 때 썼었던 코드는 다음과 같습니다. 

func bodycheck(w http.ResponseWriter, r *http.Request) []byte {
    getlength := r.ContentLength
    savebody := make([]byte, getlength)
    r.Body.Read(savebody)
    log.Println("[DEBUG]", string(savebody))
    log.Println("[DEBUG] len: ", len(savebody))
    return savebody
}

여기서 더 많은 데이터를 가져오기 위한 방법은 너무나 간단했습니다.

savebody, _ = ioutil.ReadAll(r.Body) 을 사용하면 됐었습니다.

// body값 가져오는 함수.
func bodycheck(w http.ResponseWriter, r *http.Request) ([]byte, int) {
	getlength := r.ContentLength
	savebody := make([]byte, getlength)
	// r.Body.Read(savebody)
	savebody, _ = ioutil.ReadAll(r.Body)
	defer r.Body.Close()
	leng := len(savebody)
	log.Println("[DEBUG]", string(savebody))
	log.Println("[DEBUG] len: ", leng)
	return savebody, leng
}

저 두 코드의 차이점을 살펴보자면 io.Reader 인터페이스의 Read() 함수는 한번에 모든 데이터를 반환할 것을 장담하지 않습니다.

 

io.EOF error가 반환되거나 원하는 길이만큼 읽혔을 때까지 반복적으로 호출해야 합니다.

ioutil 패키지의 ReadAll()은 EOF를 만날 때까지 Read를 해주는 유틸리티 함수입니다.

http 공식 문서에서도 언급하기를 r.Body를 다 썼으면 Close를 호출해야 합니다. 그래서 defer를 써서 닫아주면 됩니다.

 

그랬더니 무한정의 데이터가 log파일에 쌓이는 것을 알 수 있었습니다.

728x90
반응형
그리드형

댓글을 달아 주세요