크래시는 아닌데… 문제가 발생한 나의 코드, 어떻게 찾을까?

무료 플랜 IMQA LITE로 커스텀 에러 설정하여 모든 에러를 관리하세요!

작성일 2022년 09월 21일

* 해당 포스트는  [이럴 땐 이렇게! 크래시편] 의 추가 가이드입니다.

앱에서 발생하는 장애의 종류는 매우 다양합니다. 하지만 이러한 장애로 인해 앱이 꺼지면 절대로 안 되겠죠.
IMQA는 앱 크래시가 발생한 경우 크래시 데이터를 자동으로 수집합니다. 그래서 고객이 앱을 사용하다 강제 종료되면, 그때 발생한 크래시 정보를 상세히 확인할 수 있습니다.

IMQA CRASH


실제로 앱을 운영하다 보면 앱이 꺼지는 크래시가 아닌 비즈니스 로직에서 발생한 Exception이 고객의 장애로 이어지는 경우가 많은데요. 요즘 앱 사용 시 흔히 발생하는 장애를 통해 한번 확인해 볼까요?

💬 신입 개발자 복호 씨의 이야기

신입 개발자 복호 씨는 카카오 로그인 API의 APP_KEY가 만료되어 교체하여 앱을 배포하라는 업무를 받았습니다. debug 버전으로 깔끔하게 테스트를 하고, release 버전으로 Build Type을 바꾼 후 앱을 빌드 하여 마켓에 업로드하여 앱 버전을 업데이트 후 퇴근하였죠.

하지만 다음날 출근하니 로그인이 되지 않는 장애가 발생하고 있었고, 확인해 보니 debug 모드의 string.xml 파일과 release 모드의 string.xml 파일이 따로 존재하고 있음을 알게 되었습니다. debug 모드의 string.xml에 있는 app_key만 변경한 것입니다.

신입 개발자 복호 씨는 팀장님한테 크게 혼이 났고 IMQA로 Crash를 확인해 보았으나 수집된 크래시가 없다는 걸 확인하게 되었습니다.

요즘은 앱에서 로그인할 때 카카오나 네이버, 페이스북 등 간편한 로그인 연동을 대부분 이용하는데요. 위 사례처럼 오류가 발생한다면 고객이 이탈할 뿐만 아니라 브랜드 이미지까지 하락하기 때문에 반드시 관리가 필요합니다.

그렇다면, IMQA는 이러한 로그인 장애를 모니터링할 수 없었던 것일까요?

복호 씨의 앱을 살펴보죠.

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        KakaoSdk.init(this, "KAKAO_NATIVE_APP_KEY");
    }

}

앱의 Application 코드에서 KakaoSdk.init 을 통해 카카오 SDK를 올리고 있습니다.

이번 샘플 코드에서는 일부러 위와 같이 잘못된 APPKEY 값을 넣어보겠습니다.

public class MainActivity extends AppCompatActivity {
    private ImageButton btn_login;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btn_login = findViewById(R.id.btn_login);

        btn_login.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                UserApiClient.getInstance().loginWithKakaoTalk(MainActivity.this,(oAuthToken, error) -> {
                    if (error != null) {
                        Log.e(TAG, "로그인 실패", error);
                    } else if (oAuthToken != null) {
                        Log.i(TAG, "로그인 성공(토큰) : " + oAuthToken.getAccessToken());

                        UserApiClient.getInstance().me((user, meError) -> {
                            if (meError != null) {
                                Log.e(TAG, "사용자 정보 요청 실패", meError);
                            } else {
                                System.out.println("로그인 완료");
                                Log.i(TAG, user.toString());
                                {
                                    Log.i(TAG, "사용자 정보 요청 성공" +
                                            "\\n회원번호: "+user.getId() +
                                            "\\n이메일: "+user.getKakaoAccount().getEmail());
                                }
                                Account user1 = user.getKakaoAccount();
                                System.out.println("사용자 계정" + user1);
                            }
                            return null;
                        });
                    }
                    return null;
                });

            }
        });

...

Activity 코드에서는 버튼에 카카오 로그인을 연결하는 로직을 넣었는데요.
디버깅을 위해 로그인 성공과 실패에 따라 로그를 넣어봤습니다.

일부러 잘못된 APPKEY를 넣고 앱을 실행하고 로그를 확인해 보겠습니다.

2022-09-14 20:41:53.235 com.kakaologin_sample E/사용자: 로그인 실패

다음과 같이 Logcat에서 로그인 실패 로그가 뜨는데요. 하지만 앱이 꺼지진 않았습니다.

이 경우, IMQA를 연동하면 해당 에러가 수집될까요?
IMQA CRASH는 크래시 정보를 수집하기 때문에 앱이 꺼지지 않으면 자동으로 수집하지 않습니다. 그렇다면, 크래시는 아니지만 위와 같은 장애는 과연 어떻게 수집할 수 있을까요?

답은 커스텀 에러를 설정하는 것입니다!

다음 소스코드에 커스텀 에러를 설정해 보겠습니다.

@Override
            public void onClick(View v) {
                UserApiClient.getInstance().loginWithKakaoTalk(MainActivity.this,(oAuthToken, error) -> {
                    if (error != null) {
                        Log.e(TAG, "로그인 실패", error);
                        **IMQACrashAgent.SendException((Exception) error, "ERROR TAG", ErrorRank.Major);**
                    } else if (oAuthToken != null) {
                        Log.i(TAG, "로그인 성공(토큰) : " + oAuthToken.getAccessToken());

                        UserApiClient.getInstance().me((user, meError) -> {
                            if (meError != null) {
                                Log.e(TAG, "사용자 정보 요청 실패", meError);
                            } else {
                                System.out.println("로그인 완료");
                                Log.i(TAG, user.toString());
                                {
                                    Log.i(TAG, "사용자 정보 요청 성공" +
                                            "\\n회원번호: "+user.getId() +
                                            "\\n이메일: "+user.getKakaoAccount().getEmail());
                                }
                                Account user1 = user.getKakaoAccount();
                                System.out.println("사용자 계정" + user1);
                            }
                            return null;
                        });
                    }
                    return null;
                });

            }

해당 코드의 5번째 라인 코드에 커스텀 에러를 전송하는 코드를 넣었습니다.

IMQACrashAgent.SendException((Exception) error, "ERROR TAG", ErrorRank.Major);

그럼, IMQA Crash에서 다음과 같이 Crash를 수집할 수 있게 됩니다.
이때 Major로 파라미터를 넣으면, 메이저 등급이 표시되는데요. 해당 크래시를 클릭하여 상세페이지로 접속하면 다음과 같이 에러가 발생한 스택 트레이스도 확인할 수 있습니다.

커스텀 로그도 기존 크래시 로그처럼 모든 기능을 똑같이 사용할 수 있습니다.

IMQA CRASH 에러 상세

Intent를 통한 외부 앱 연동이나 요즘 많이 발생하는 3rd party 라이브러리에서의 에러는 크래시 솔루션에서 확인할 수 없습니다.

예를 들어, 고객이 결제 버튼을 눌렀는데 비즈니스 Exception이 발생하여 결제 실패를 할 수 있겠죠.
또한 금융권에서는 안전성을 위해 여러 가지 보안 인증 관련된 툴(백신, 위 변조 방지 프로그램, 난독화 솔루션 등)을 도입하는데요. 이러한 보안 모듈에서 통신 오류나 보안 KEY 연동 이슈로 장애가 발생합니다.
이 경우 앱이 종료된 것이 아니기 때문에 크래시로 확인할 수 없죠. 이 외에도 다양한 장애가 발생하지만, 단지 크래시 솔루션에는 수집되지 않기 때문에 놓치고 있는 것입니다.

위와 같은 상황에서 발생한 콜백 정보를 넣어서 커스텀 에러를 활용하면, 크래시 외 비즈니스에서 발생하는 모든 에러들을 모니터링할 수 있습니다.

여러분 앱  try~catch 블록에 IMQA의 커스텀 에러를 추가하면 어떨까요?
지금 바로 IMQA LITE에서 커스텀 에러 설정하고, 모든 에러를 관리해 보세요!

커스텀 에러 설정 가이드도 확인해 보세요!  ▶️가이드 확인하기

Share on

Tags

IMQA 뉴스레터 구독하기

국내외 다양한 기술 소식을 선별하여 매월 전달해드립니다. IMQA 뉴스레터를 통해 기술 이야기를 함께해보세요.

구독하기