Kafka로 이루어진 로그 수집 서버가 수정 사항이 생겨 코드를 수정할 일이 생겼습니다.
발생한 로그들을 정의한 Struct에 입력받아 로그 파일과, 파일들을 만들어주는 함수가 있는데
func create(w http.ResponseWriter, r *http.Request) {
defer FailSendding(w)
var inArr []Exam //input slice define
body, leng := bodycheck(w, r)
err := json.Unmarshal(body, &inArr)
if err != nil {
SenddingToPanic(err)
}
for _, in := range inArr {
MSGCheckking(&in, string(body), leng) // check & file not save
}
for _, in := range inArr {
MSGSendding(&in, string(body))
}
OkSendding("OK", w) // ok send
}
먼저 들어온 값(body)를 body를 체크해주는 함수를 통해 체크 후, Unmarshal하여 JSON데이터 한 줄 한 줄을
for루프들을 통해 먼저 메세지가 정상인지 아닌지를 체크 후, 그 다음 Topic에 메세지를 보내주는 함수입니다.
여기 중 메세지(JSON date)를 체크하는 함수 안에서 보내야 하는 JSON 데이터 중 필수값 부분을 확인하는 부분이 있는데 그 부분을 따로 함수화할 필요가 있었습니다.
처음에는
func RequiredChecking(in *Exam) error {
var err error
if len(in.a) == 0 {
err = errors.New("a의 데이터가 올바르게 입력되지 않았습니다. 입력값을 확인하세요.")
log.Println("a : ", json.a)
return err
} else if len(in.b) == 0 {
err = errors.New("b의 데이터가 올바르게 입력되지 않았습니다. 입력값을 확인하세요.")
log.Println("b : ", json.b)
return err
} else if len(in.c) == 0 {
err = errors.New("c의 데이터가 올바르게 입력되지 않았습니다. 입력값을 확인하세요.")
log.Println("c : ", json.c)
return err
....
} else {
return nil
}
}
이런식의 코드를 사용하여 체크를 했는데 문제가 있었습니다.
in.a의 값이 0이 아니면 그 밑에 있는 else if문들은 실행이 되지 않았으며, 설령 c값이 0일 때는
a 검사 후 -> b 검사 후 -> c 검사 -> d검사하는 효율적이지 못한 구조가 되버립니다.
그래서 a~c까지 한번에 검사할 필요가 있었습니다.
그렇게 나오게 된 구조가
func RequiredChecking(in *Exam) error {
if len(in.a) == 0 {
err = errors.New("필수 데이터가 올바르게 입력되지 않았습니다. 입력값을 확인하세요.")
log.Println("a :", in.a)
return err
}
if len(in.b) == 0 {
err = errors.New("필수 데이터가 올바르게 입력되지 않았습니다. 입력값을 확인하세요.")
log.Println("b :", in.b)
return err
}
if len(in.c) == 0 {
err = errors.New("필수 데이터가 올바르게 입력되지 않았습니다. 입력값을 확인하세요.")
log.Println("c :", in.c)
return err
}
...
return nil
}
이런 구조가 되었는데 이 부분을 SWITCH CASE문을 사용해도 되지 않을까? 싶었는데 그건 if - else if 랑 같다는 의견이 있어 그렇게 하지 않았습니다.
그렇게 해서 2가지의 선택 사항이 생겼는데
1. 저런식으로 함수 안에서 if문을 4번 돌린다.
2. RequiredChecking()를 사용하는 부분에서 4번을 돌린다.
였습니다.
2번을 하게 된다면
func aaaa () {
eRequiredChecking(in.a)
eRequiredChecking(in.b)
eRequiredChecking(in.c)
eRequiredChecking(in.d)
}
func RequiredChecking(in *Exam) error {
if len(in) == 0 {
err = errors.New("필수 데이터가 올바르게 입력되지 않았습니다. 입력값을 확인하세요.")
log.Println("a :", in)
return err
}
return nil
}
이런식의 코드가 생성되는 것인데
여기서 어떤게 나을지 고민이 생겼고, 그러다 aaaa라는 함수 안에서 RequiredChecking의 인자 값을 가변인자로 넣고,
그 가변인자들을 for문으로 돌려 기존 조건값에 맞는 변수의 name을 출력할 수 있다면 더 코드의 양이 줄어들지 않겠냐는 의견이 있었습니다.
check ("a,b,c")
check (in.....) {
for( in)
if len(in)
err = errors.New("asdsaaa")
log.println(변수이름, 변수값)
return err;
그래서 위와 같은 의사코드가 나왔고, Golang에서의 가변인자를 받을 수 있는지, 변수의 name을 출력할 수 있는지를 찾아야 했습니다.
Golang에서의 가변인자를 받을 수 있는 부분이 있어 이 부분은 쉽게 되었지만 변수의 name을 출력할 수 있는 부분을 찾지 못해 reflect부분도 뒤져보고 하였으나 빈 값에 대해서 어떻게 해야 할 지 몰랐습니다.
그래서
func aaaa () {
err = RequiredValueChecking(in.a, in.b, in.c, in.d)
if err != nil {
SenddingToPanic(err)
}
}
func RequiredChecking(in ...string) error {
var err error
for _, value := range in {
if len(value) != 0 {
err = errors.New("필수 데이터가 올바르게 입력되지 않았습니다. 입력값을 확인하세요.")
fmt.Printf(reflect.ValueOf(value).String(), in)
return err
}
}
return nil
}
위와 같은 코드를 작성했지만 여전히 변수의 name 부분을 찾는 부분에서 해결 되지 못했습니다.
물론
fmt.Printf("%v\n", in)
만 해도 기능은 구현된다 하지만 방대한 데이터 속에서 어떤 데이터가 빠졌는지 빨리 파악해야 했기 때문에
그 부분을 넣고 싶었습니다.
그러다 찾고 찾다 못찾아 생각해 낸 부분이 for문을 돌려 i번째 값을 넣는 것이였습니다.
for i := 0; i < len(in); i++ {
if len(in[i]) == 0 {
errorstring := "Service : " + in[0] + "|" + "Task : " + in[1] + "|" + "LogSource : " + in[2] + "|" + "LTZ : " + in[3]
err = errors.New("필수 데이터가 올바르게 입력되지 않았습니다. 입력값을 확인하세요." + errorstring)
// fmt.Printf(reflect.ValueOf(value).String(), in)
return err
}
}
return nil
꿩 대신 닭이 이럴 때 쓰나봅니다 ㅋㅋㅋㅋ
쉽게 값과 값 사이를 구분하기 위해 "|"로 구분 지어 주었고, 이렇게 해서 JSON nil값 Check 함수가 완성되었습니다!
'프로그래밍(Web) > 업무관련' 카테고리의 다른 글
[바미] Golang reflect 함수 사용하여 필수 값 체크 함수 만들기. (0) | 2021.05.08 |
---|---|
[바미] Golang JSON에 입력된 UTC 시간 값 비교하기 (0) | 2021.05.04 |
[바미] Golang 같은 변수의 값 체크 시 “suspect or ” warnning 해결 방법 (0) | 2021.05.03 |
[바미] 고통스런 yarn build (0) | 2021.03.19 |
[바미] Golang Kafka(sarama) + negroni 연동완료. (0) | 2021.02.23 |