feat(observability): add structured application logging
Emit correlated JSON logs from the API and FunASR services, propagate request IDs to the client, and configure bounded opt-in Docker logging. Document the host-wide Grafana/Loki query workflow and keep observability deployment ownership outside the application repository.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import {
|
||||
copyApiRequestId,
|
||||
createFeedbackRecord,
|
||||
createVoiceLesson,
|
||||
ensureFeedbackSession,
|
||||
@@ -6,6 +7,7 @@ import {
|
||||
generateFeedbackFromVoice,
|
||||
getActiveFeedbackSession,
|
||||
getApiErrorMessage,
|
||||
getApiRequestId,
|
||||
listProfiles,
|
||||
markVoiceLessonApplied,
|
||||
retryVoiceSegment,
|
||||
@@ -114,7 +116,8 @@ Page({
|
||||
voiceStatus: '语音录入',
|
||||
voiceActionable: false,
|
||||
primaryActionText: '保存反馈',
|
||||
errorMessage: ''
|
||||
errorMessage: '',
|
||||
errorRequestId: ''
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
@@ -189,7 +192,7 @@ Page({
|
||||
},
|
||||
|
||||
async loadProfiles() {
|
||||
this.setData({ loading: true, errorMessage: '' })
|
||||
this.setData({ loading: true, errorMessage: '', errorRequestId: '' })
|
||||
try {
|
||||
const profiles = await listProfiles()
|
||||
const matchedProfileIndex = profiles.findIndex((profile) => profile.id === this.data.draft.profileId)
|
||||
@@ -203,7 +206,7 @@ Page({
|
||||
})
|
||||
await this.loadActiveSession(profileId)
|
||||
} catch (error) {
|
||||
this.setData({ errorMessage: getApiErrorMessage(error) })
|
||||
this.setData({ errorMessage: getApiErrorMessage(error), errorRequestId: getApiRequestId(error) })
|
||||
} finally {
|
||||
this.setData({ loading: false })
|
||||
}
|
||||
@@ -227,7 +230,7 @@ Page({
|
||||
this.syncVoicePresentation(session)
|
||||
this.scheduleVoicePolling(session)
|
||||
} catch (error) {
|
||||
this.setData({ errorMessage: getApiErrorMessage(error) })
|
||||
this.setData({ errorMessage: getApiErrorMessage(error), errorRequestId: getApiRequestId(error) })
|
||||
}
|
||||
},
|
||||
|
||||
@@ -309,6 +312,10 @@ Page({
|
||||
void this.loadProfiles()
|
||||
},
|
||||
|
||||
copyRequestId() {
|
||||
copyApiRequestId(this.data.errorRequestId)
|
||||
},
|
||||
|
||||
onProfileChange(event: PickerEvent) {
|
||||
this.clearDraftSaveTimer()
|
||||
const selectedProfileIndex = Number(event.detail.value)
|
||||
|
||||
@@ -6,7 +6,13 @@
|
||||
<text class="page-subtitle">填写课堂表现并保存到教学反馈记录。</text>
|
||||
|
||||
<view wx:if="{{errorMessage}}" class="status-banner">
|
||||
<text>{{errorMessage}}</text>
|
||||
<view class="status-copy">
|
||||
<text>{{errorMessage}}</text>
|
||||
<view wx:if="{{errorRequestId}}" class="status-request-id">
|
||||
<text>请求编号:{{errorRequestId}}</text>
|
||||
<text class="status-action" bindtap="copyRequestId">复制</text>
|
||||
</view>
|
||||
</view>
|
||||
<text class="status-action" bindtap="retryLoad">重试</text>
|
||||
</view>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user