-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(@yourssu/logging-system): fix 10th lost-log #68
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
좀 빡세게 리뷰했습니다. 현재 구조에서 접근법은 괜찮은데, 좀 더 근본적인 리팩토링이 동반되었으면 좋겠습니다.
@@ -1,36 +1,32 @@ | |||
import { LogRequestList, LogResponse, LogType } from './types/LogType'; | |||
|
|||
export const SetLocalStorageClear = () => { | |||
const list: any[] = []; | |||
const list: LogType[] = []; | |||
localStorage.setItem('yls-web', JSON.stringify(list)); | |||
}; | |||
|
|||
export const SetLocalStorage = async ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR의 내용과는 관계없습니다만, 이거 왜 SetLocalStorage
인가요? 실제 하는 일은 로그를 전송하는 건데, 관심사 분리를 확실히 하고 로컬스토리지 저장과 로그 전송을 순차 실행하는 새로운 함수를 만드셔야 할 것 같습니다. 제가 YLS 코드에 대한 배경 지식이 없었는데, 지금 리뷰하면서 살펴보니 고쳐야 할 부분이 많아 보이네요.
예시) SetLocalStorage
함수를 storeLog
, sendStoredLogs
함수로 분리 후 상위 호출 함수에서 두 함수를 순서대로 호출하도록 리팩토링
일단 이 PR과 관계없으므로 resolve 되지 않아도 Approve는 가능합니다.
const req: LogRequestList = { | ||
logRequestList: remainList, | ||
}; | ||
const list: LogType[] = JSON.parse(localStorage.getItem('yls-web') as string) || []; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const list: LogType[] = JSON.parse(localStorage.getItem('yls-web') as string) || []; | |
const list: LogType[] = JSON.parse(localStorage.getItem('yls-web') as string) ?? []; |
||
말고 nullish coalescing 연산자(??
) 활용하시면 의도에 맞으실 것 같습니다.
@@ -1,36 +1,32 @@ | |||
import { LogRequestList, LogResponse, LogType } from './types/LogType'; | |||
|
|||
export const SetLocalStorageClear = () => { | |||
const list: any[] = []; | |||
const list: LogType[] = []; | |||
localStorage.setItem('yls-web', JSON.stringify(list)); | |||
}; | |||
|
|||
export const SetLocalStorage = async ( | |||
logger: LogType, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 PR만의 문제가 아닌 것 같긴 한데, 얘 이름이 logger인 이유를 모르겠네요. log 데이터 그 자체이므로 이름 수정이 필요합니다.
}; | ||
const list: LogType[] = JSON.parse(localStorage.getItem('yls-web') as string) || []; | ||
list.push(logger); | ||
localStorage.setItem('yls-web', JSON.stringify(list)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
localStorage.setItem('yls-web', JSON.stringify(list)); | |
localStorage.setItem('yls-web.logs', JSON.stringify(list)); |
yls-web.logs
처럼 데이터의 정확한 명칭을 지정해서 의도를 명확히 하고, 앞으로 다른 데이터가 추가되어도 네이밍 문제가 생기지 않도록 하면 좋겠습니다.
@@ -1,36 +1,32 @@ | |||
import { LogRequestList, LogResponse, LogType } from './types/LogType'; | |||
|
|||
export const SetLocalStorageClear = () => { | |||
const list: any[] = []; | |||
const list: LogType[] = []; | |||
localStorage.setItem('yls-web', JSON.stringify(list)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
localStorage.setItem('yls-web', JSON.stringify(list)); | |
localStorage.setItem('yls-web', "[]"); |
이거 그냥 이렇게 해도 되지 않나요?
@@ -1,36 +1,32 @@ | |||
import { LogRequestList, LogResponse, LogType } from './types/LogType'; | |||
|
|||
export const SetLocalStorageClear = () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
export const SetLocalStorageClear = () => { | |
export const ClearLocalStorage = () => { |
이것도 네이밍이 미묘하네요.
try { | ||
await putLog(req); | ||
} catch (e) { | ||
console.error('Failed to post log'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 오류는 프로덕션에는 안나면 좋겠네요. 어짜피 Network 탭에서 요청 상태를 확인 가능하니까요.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
혹시나 에러 로깅을 하고 싶으시다면 e
도 포함해서 로깅해주시면 좋겠습니다.
console.error('Failed to post log'); | |
console.error('Failed to post log', e); |
await putLog(req); | ||
} catch (e) { | ||
console.error('Failed to post log'); | ||
const remainList: LogType[] = JSON.parse(localStorage.getItem('yls-web') as string) || []; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remainList
라는게 아직 못 보낸 로그처럼 느껴져서 logsAfterRequest
같은 느낌으로 수정했으면 좋겠습니다.
remainList.unshift(...list); | ||
localStorage.setItem('yls-web', JSON.stringify(remainList)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remainList.unshift(...list); | |
localStorage.setItem('yls-web', JSON.stringify(remainList)); | |
list.push(...remainList); | |
localStorage.setItem('yls-web', JSON.stringify(list)); |
이편이 깔끔하지 않을까요?
첨언) 타임스탬프 구현이 아닌 이 구현도 문제가 존재합니다. 반례 드릴게요.
개인적으로는 중복 전송보다 로그 유실이 더 큰 문제로 느껴져서 타임스탬프 구현을 선호합니다. 만약 로그 중복이 걱정되신다면 로그 스펙에 고유의 임의 ID를 추가한다면 완벽히 해결할 수 있겠네요. |
아하 이런 반례가 있군요... 저는 해당 상황을 생각하지 못했는데 만약 타임 스탬프로 구현한다고 해도 해당 상황에서 로그 중복 문제가 발생할 것 같네요. 제 생각에는 로그 전송이 실패하는 경우보다는 로그 중복 전송이 일어나는 경우가 더 많을 것으로 예상되어서요. (로그 전송 후 로컬스토리지에서 로그를 제거하기 전에 사용자가 이탈). 물론 로그 손실 문제 자체가 더 큰 문제인 것은 동의합니다. 로그 손실 + 중복 문제를 동시에 해결하기 위해 타임 스탬프 + 임의 ID를 사용하는 방식을 적용해서 해결해보겠습니다. 네이밍의 경우에는 일단 기존에 개발된 내용을 그대로 적용한 거라서 딱히 수정하진 않았는데, 수정할 필요성이 있어 보입니다. 근본적인 리팩토링이 필요하다는 의견도 동의하구요. 일단 이 PR과 관련 있는 부분들만 수정해서 머지한 후 이슈를 새로 파서 대대적인 리팩토링을 진행하겠습니다. |
네네 그래도 리뷰 요청 주셨으니 빡세게 리뷰 드렸는데... 어떻게 느끼셨을지 모르겠네요. 지금 PR과 관계없는 내용이 많았는데, 관계 있는 내용만 수정하셔서 리뷰 요청 주시면 어푸룹 드리겠습니다. 화이팅! 나머지 구조적인 부분은 천천히 작업하셔도 충분하지 않나 싶습니다. |
1️⃣ 어떤 작업을 했나요? (Summary)
기존 코드에 영향을 미치지 않는 변경사항
기존 코드에 영향을 미치는 변경사항
remainList
를 전송하기 때문입니다. 지금은 10번 째 로그가 들어오자마자 이를 포함해 전송합니다.버그 픽스
2️⃣ 알아두시면 좋아요!
3️⃣ 추후 작업
4️⃣ 체크리스트 (Checklist)
main
브랜치의 최신 코드를pull
받았나요?