gorm sql show query에 대하여

임태빈·2023년 12월 24일
0

go

목록 보기
13/13
post-thumbnail

배경

golang의 orm 중 하나인 gorm을 사용하면서 내가 사용하는 코드에 대한 sql query문이 어떻게 나오는지에 대해 궁금해졌다.
성능을 최적화하기 위해서도 알아야 하는 부분이기도 하다.

확인 방법

sql query를 확인하기 위해서 다음과 같이 테스트를 진행했다.

  1. config에 logger 설정하기

    db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{
    	Logger: logger.Default.LogMode(logger.Info),
    })

    설정후, 테스트를 해보니 아래와 같이 예시를 얻을 수 있었다.

    정상적으로 쿼리를 조회가 되는 것을 확인했다.

    하지만 여기에 문제가 있다.
    사진 내용에서 알 수 있듯이 내가 어떤 데이터를 통해 조회를 하고 있는지 볼 수 있다는 것이다.

    많은 서버개발자들이 사용하고 있는 java 진영의 JPA에 경우 쿼리를 조회하게 되면 where 조건절의 값들은 다 ?
    처리가 된다. 즉 prepared statement를 활용해서 처리가 된다는 것이다.

    gorm은 defulat 셋업이 아니다. 따라서 이에 대해 추가적으로 설정을 해주어야 한다.

  1. config에 prepared Statemet 관련 옵션 추가하기

    db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{
    	PrepareStmt: true,
    	Logger: logger.Default.LogMode(logger.Info),
    })

    위와 같이 config에 PrepareStmt 옵션을 추가해주었다.
    하지만 1번과 동일하게 email 부분에 값이 들어와 있었다.

    옵션에 대한 설명을 다시 보니,

    PrepareStmt 옵션은 query 캐싱만 해주는 것이었다. show query 옵션 관련된 부분은 제외대어 있었다.

    따라서 나는 logger가 이 문제를 해결할 수 있을지 않을까라고 생각했다.

  1. 새로운 logger 만들기
    gorm 공식문서를 보다가 다음과 같은 옵션을 찾을 수 있었다.

    type Config struct {
    	SlowThreshold             time.Duration
    	Colorful                  bool
    	IgnoreRecordNotFoundError bool
    	ParameterizedQueries      bool
    	LogLevel                  LogLevel
    }

    이 옵션들은 gorm logger에서 사용하는 옵션들이다.
    여기서 ParameterizedQueries 이 옵션이 console log를 찍어줄때 ? 혹은 $1 나올 수 있도록해준다고 한다.
    관련된 옵션을 어디서 사용하고 있는지 확인해보니 다음 코드에서 사용하고 있었다.

    // Trace print sql message
    func (l logger) ParamsFilter(ctx context.Context, sql string, params ...interface{}) (string, []interface{}) {
    	if l.Config.ParameterizedQueries {
    		return sql, nil
    	}
    	return sql, params
    }

    주석에도 나와있듯이 Trace print sql message로 되어 있다. 이거 자체가 params 값을 넣을것이지 아닌지를 설정한다고 볼 수 있다.
    그래서 나는 다음과 같이 새로운 logger를 만들었다.

     log := logger.New(log.New(os.Stdout, "\r\n", log.LstdFlags), logger.Config{
         SlowThreshold:             200 * time.Millisecond,
         LogLevel:                  logger.Info,
         IgnoreRecordNotFoundError: false,
         Colorful:                  false,
         ParameterizedQueries:      true,
     })
    
     db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{
         PrepareStmt: true,
         Logger: log,
     })

위와 같이 만들어서 적용해보니 컬럼에 내가 요청한 값이 안들어가고 $1이 들어간 것을 확인할 수 있었다.

결론

gorm에서 제공해주는 default logger를 사용하면 내가 조건문에 사용한 컬럼에 들어가는 값이 보인다. 보안상 문제가 될 수 있기에 조심해야한다.
그렇기에 이런 설정을 해주어서 사용하면 좋을거 같다.
추가적으로 zap logger도 커스텀해서 사용할 수 있기에 관심있는 사람들은 한번 해봐도 좋을거 같다.

profile
golang과 서버 개발을 하고 있는 개발자입니다.

0개의 댓글