Sentry-javascript: @sentry/browser ๋ฅผ ํ†ตํ•ด ํด๋ผ์ด์–ธํŠธ์˜ ๋„คํŠธ์›Œํฌ ์˜ค๋ฅ˜๋ฅผ ์–ด๋–ป๊ฒŒ ๊ฐ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

์— ๋งŒ๋“  2018๋…„ 12์›” 19์ผ  ยท  3์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: getsentry/sentry-javascript

ํŒจํ‚ค์ง€ + ๋ฒ„์ „

  • [o] @sentry/browser
  • [x] @sentry/node
  • [ ] raven-js
  • [x] raven-node _(๋…ธ๋“œ์šฉ ๋ ˆ์ด๋ธ)_
  • [ ] ๊ธฐํƒ€: Angular6 + Ngrx6

๋ฒ„์ „:

@sentry/browser": "4.4.2"

์„ค๋ช…

์•ˆ๋…•ํ•˜์„ธ์š” ์—ฌ๋Ÿฌ๋ถ„,
์œ„์—์„œ ์„ค๋ช…ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ Angular6 + Ngrx6์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
๋‚ด๊ฐ€ํ•˜๊ณ  ์‹ถ์€ ๊ฒƒ์€ webApp์ด API ํ˜ธ์ถœ์— ์‹คํŒจํ–ˆ์„ ๋•Œ Sentry์— ์˜ค๋ฅ˜๋ฅผ ๋ณด๋‚ด๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์กด์žฌํ•˜์ง€ ์•Š๋Š” /abc/3 ๋ผ๋Š” API๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.
๊ทธ๋Ÿฐ ๋‹ค์Œ ํด๋ผ์ด์–ธํŠธ์— 404 Not Found ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ์ด๊ฒƒ์€ @sentry/browser ๋ฅผ ํ†ตํ•ด Sentry์— ๋ณด๋‚ด๊ณ  ์‹ถ์€ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ฐ„๋‹จํ•œ ์„œ๋น„์Šค๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

@Injectable({
  providedIn: 'root'
})
export class SentryService {
  constructor() { }
  captureException(error: any) {
    Sentry.captureException(error.originalError || error);
    throw error;
  }
}

Angular์˜ ErrorHandler ๋ฅผ ํ™•์žฅํ•˜๋Š” SentryErrorHandler ๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

@Injectable()
export class SentryErrorHandler implements ErrorHandler {
  constructor(private sentry: SentryService) {}
  handleError(error: any): void {
    this.sentry.captureException(error);
    throw error;
  }
}

์ด ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ผ๋ฐ˜์ ์ธ js ์˜ค๋ฅ˜๋ฅผ ์ž˜ ๊ฐ์ง€ํ•ฉ๋‹ˆ๋‹ค.
abcdefg(); // <- this function doesn't exist so it occurs an error and sent to Sentry.

๊ทธ๋Ÿฐ๋ฐ ์œ„์˜ ์ฝ”๋“œ๊ฐ€ ๋„คํŠธ์›Œํฌ ์˜ค๋ฅ˜๋ฅผ ๊ฐ์ง€ํ•˜์ง€ ๋ชปํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ( ๋‚ด๊ฐ€ ๋งํ–ˆ๋“ฏ์ด /abc/3 )

๊ทธ๋ž˜์„œ Angular์˜ HttpInterceptor ErrorInterceptor ๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
    constructor(
        private _injector: Injector,
        private sentry: SentryService
    ) {}

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next.handle(req)
        .pipe(
            tap(event => {}, error => {
                if (error) {
                    this.sentry.captureException(error);
                }
            })
        );
    }
}

๊ทธ๋Ÿฐ ๋‹ค์Œ ๋„คํŠธ์›Œํฌ ์˜ค๋ฅ˜๋ฅผ ์žก์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ ๋ฌธ์ œ๋Š” ๋‚ด Sentry ๋Œ€์‹œ๋ณด๋“œ์—์„œ ์•„๋ฌด๊ฒƒ๋„ ๋ณผ ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๋‚ด Chrome ๋„คํŠธ์›Œํฌ ํƒญ์„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฉ”์‹œ์ง€๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.
"ํ‚ค๋กœ ์บก์ฒ˜๋œ ์˜ค๋ฅ˜๊ฐ€ ์•„๋‹Œ ์˜ˆ์™ธ: ์˜ค๋ฅ˜, ํ—ค๋”, ๋ฉ”์‹œ์ง€, ์ด๋ฆ„, ํ™•์ธ..."

๊ทธ๋ž˜์„œ @sentry/browser๋Š” ์ด๊ฒƒ์ด ์˜ค๋ฅ˜๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋˜ํ•œ Non-Error exception captured with keys: error, headers, message, name, okโ€ฆ ์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๋Š” ๊ฒƒ์„ ๋ฐœ๊ฒฌ ํ–ˆ์Šต๋‹ˆ๋‹ค .

์—ฌ๊ธฐ ๋‚ด ์งˆ๋ฌธ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  1. @sentry/browser๊ฐ€ ํด๋ผ์ด์–ธํŠธ ๋„คํŠธ์›Œํฌ ์˜ค๋ฅ˜๋ฅผ ์žก๊ธฐ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๊นŒ?
  2. 1์ด ์‚ฌ์‹ค์ด๋ผ๋ฉด ์–ด๋–ป๊ฒŒ ์ž‘๋™์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? (์ž˜ํ•˜๋ฉด ๊ฐ๋„ ๋ฐฉ์‹)
  3. 2๊ฐ€ false์ด๋ฉด ๋ฐฑ์—”๋“œ์—์„œ ๋„คํŠธ์›Œํฌ ์˜ค๋ฅ˜๋ฅผ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

๊ฐ์‚ฌ ํ•ด์š”!

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

@Taewa Angular๊ฐ€ ๋˜์ง„ ์˜ค๋ฅ˜ ๊ฐ์ฒด๋Š” SentryEvent ์™€ ๊ฐ™์€ ํ˜•์‹์ด ์•„๋‹™๋‹ˆ๋‹ค.

ํ•œ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์€ ์ผ๋ถ€ ์˜ค๋ฅ˜ ์ •๋ณด์™€ ํ•จ๊ป˜ captureMessage(message: string) ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ๋‚ด๊ฐ€ ์„ ํƒํ•œ ๋” ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. https://github.com/pascaliske/ngx-sentry/blob/master/projects/ngx-sentry/src/lib/sentry.interceptor.ts

๋˜ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์€ Sentry ์ด๋ฒคํŠธ ๊ฐœ์ฒด๋ฅผ ์ง์ ‘ ๋งŒ๋“ค๊ณ  captureEvent(event: SentryEvent) ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Sentry๋กœ ๋ณด๋‚ด๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋„์›€์ด ๋˜์—ˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. ๐Ÿ™‚

๋ชจ๋“  3 ๋Œ“๊ธ€

@Taewa Angular๊ฐ€ ๋˜์ง„ ์˜ค๋ฅ˜ ๊ฐ์ฒด๋Š” SentryEvent ์™€ ๊ฐ™์€ ํ˜•์‹์ด ์•„๋‹™๋‹ˆ๋‹ค.

ํ•œ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์€ ์ผ๋ถ€ ์˜ค๋ฅ˜ ์ •๋ณด์™€ ํ•จ๊ป˜ captureMessage(message: string) ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ๋‚ด๊ฐ€ ์„ ํƒํ•œ ๋” ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. https://github.com/pascaliske/ngx-sentry/blob/master/projects/ngx-sentry/src/lib/sentry.interceptor.ts

๋˜ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์€ Sentry ์ด๋ฒคํŠธ ๊ฐœ์ฒด๋ฅผ ์ง์ ‘ ๋งŒ๋“ค๊ณ  captureEvent(event: SentryEvent) ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Sentry๋กœ ๋ณด๋‚ด๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋„์›€์ด ๋˜์—ˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. ๐Ÿ™‚

@pascaliske ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค
๋‚˜๋Š” ์‹ค์ œ๋กœ ๋‹น์‹ ์ด ์–ธ๊ธ‰ ํ•œ captureMessage(message: string) ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค.
์•ž์œผ๋กœ ์ฐพ์•„์˜ค์‹œ๋Š” ๋ถ„๋“ค์—๊ฒŒ ๋„์›€์ด ๋  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค :)

์ด ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋œ ๊ฒƒ ๊ฐ™์•„์„œ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰