Skip to content
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: upload native logs #45905

Merged
merged 14 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions ios/NotificationServiceExtension/NotificationService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,18 @@
import AirshipServiceExtension
import os.log
import Intents
import AppLogs

class NotificationService: UANotificationServiceExtension {

var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent: UNMutableNotificationContent?
let log = OSLog(subsystem: Bundle.main.bundleIdentifier ?? "com.expensify.chat.dev.NotificationServiceExtension", category: "NotificationService")
let appLogs: AppLogs = .init()

deinit {
appLogs.forwardLogsTo(appGroup: "group.com.expensify.new")
}

override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
os_log("[NotificationService] didReceive() - received notification", log: log)
kirillzyusko marked this conversation as resolved.
Show resolved Hide resolved
Expand Down Expand Up @@ -42,7 +48,7 @@ class NotificationService: UANotificationServiceExtension {
do {
notificationData = try parsePayload(notificationContent: notificationContent)
} catch ExpError.runtimeError(let errorMessage) {
os_log("[NotificationService] configureCommunicationNotification() - couldn't parse the payload '%@'", log: log, type: .error, errorMessage)
os_log("[NotificationService] configureCommunicationNotification() - couldn't parse the payload '%{public}@'", log: log, type: .error, errorMessage)
contentHandler(notificationContent)
return
} catch {
Expand Down Expand Up @@ -212,7 +218,7 @@ class NotificationService: UANotificationServiceExtension {
let data = try Data(contentsOf: url)
return INImage(imageData: data)
} catch {
os_log("[NotificationService] fetchINImage() - failed to fetch avatar. reportActionID: %@", log: self.log, type: .error, reportActionID)
os_log("[NotificationService] fetchINImage() - failed to fetch avatar. reportActionID: %{public}@", log: self.log, type: .error, reportActionID)
return nil
}
}
Expand Down
1 change: 1 addition & 0 deletions ios/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ end

target 'NotificationServiceExtension' do
pod 'AirshipServiceExtension'
pod 'AppLogs', :path => '../node_modules/react-native-app-logs/AppLogsPod'
end

pod 'FullStory', :http => 'https://ios-releases.fullstory.com/fullstory-1.52.0-xcframework.tar.gz'
38 changes: 34 additions & 4 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ PODS:
- AppAuth/Core (1.7.5)
- AppAuth/ExternalUserAgent (1.7.5):
- AppAuth/Core
- AppLogs (0.1.0)
- boost (1.84.0)
- DoubleConversion (1.1.6)
- EXAV (14.0.7):
Expand Down Expand Up @@ -1564,6 +1565,27 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- react-native-app-logs (0.2.2):
- DoubleConversion
- glog
- hermes-engine
- RCT-Folly (= 2024.01.01.00)
- RCTRequired
- RCTTypeSafety
- React-Core
- React-debug
- React-Fabric
- React-featureflags
- React-graphics
- React-ImageManager
- React-NativeModulesApple
- React-RCTFabric
- React-rendererdebug
- React-utils
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- react-native-blob-util (0.19.4):
- DoubleConversion
- glog
Expand Down Expand Up @@ -1946,7 +1968,7 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- react-native-view-shot (3.8.0):
- react-native-view-shot (4.0.0-alpha.3):
- React-Core
- react-native-webview (13.8.6):
- DoubleConversion
Expand Down Expand Up @@ -2689,6 +2711,7 @@ PODS:

DEPENDENCIES:
- AirshipServiceExtension
- AppLogs (from `../node_modules/react-native-app-logs/AppLogsPod`)
- boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`)
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
- EXAV (from `../node_modules/expo-av/ios`)
Expand Down Expand Up @@ -2738,6 +2761,7 @@ DEPENDENCIES:
- React-Mapbuffer (from `../node_modules/react-native/ReactCommon`)
- React-microtasksnativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/microtasks`)
- "react-native-airship (from `../node_modules/@ua/react-native-airship`)"
- react-native-app-logs (from `../node_modules/react-native-app-logs`)
- react-native-blob-util (from `../node_modules/react-native-blob-util`)
- "react-native-cameraroll (from `../node_modules/@react-native-camera-roll/camera-roll`)"
- react-native-config (from `../node_modules/react-native-config`)
Expand Down Expand Up @@ -2851,6 +2875,8 @@ SPEC REPOS:
- Turf

EXTERNAL SOURCES:
AppLogs:
:path: "../node_modules/react-native-app-logs/AppLogsPod"
boost:
:podspec: "../node_modules/react-native/third-party-podspecs/boost.podspec"
DoubleConversion:
Expand Down Expand Up @@ -2946,6 +2972,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/react/nativemodule/microtasks"
react-native-airship:
:path: "../node_modules/@ua/react-native-airship"
react-native-app-logs:
:path: "../node_modules/react-native-app-logs"
react-native-blob-util:
:path: "../node_modules/react-native-blob-util"
react-native-cameraroll:
Expand Down Expand Up @@ -3096,6 +3124,7 @@ SPEC CHECKSUMS:
AirshipFrameworkProxy: dbd862dc6fb21b13e8b196458d626123e2a43a50
AirshipServiceExtension: 9c73369f426396d9fb9ff222d86d842fac76ba46
AppAuth: 501c04eda8a8d11f179dbe8637b7a91bb7e5d2fa
AppLogs: 3bc4e9b141dbf265b9464409caaa40416a9ee0e0
boost: 26992d1adf73c1c7676360643e687aee6dda994b
DoubleConversion: 76ab83afb40bddeeee456813d9c04f67f78771b5
EXAV: afa491e598334bbbb92a92a2f4dd33d7149ad37f
Expand Down Expand Up @@ -3171,6 +3200,7 @@ SPEC CHECKSUMS:
React-Mapbuffer: 1c08607305558666fd16678b85ef135e455d5c96
React-microtasksnativemodule: f13f03163b6a5ec66665dfe80a0df4468bb766a6
react-native-airship: e10f6823d8da49bbcb2db4bdb16ff954188afccc
react-native-app-logs: 91a04f691f2db7c1d6153bce31cab3922e6873f4
react-native-blob-util: 221c61c98ae507b758472ac4d2d489119d1a6c44
react-native-cameraroll: 478a0c1fcdd39f08f6ac272b7ed06e92b2c7c129
react-native-config: 5ce986133b07fc258828b20b9506de0e683efc1c
Expand All @@ -3188,7 +3218,7 @@ SPEC CHECKSUMS:
react-native-quick-sqlite: 7c793c9f5834e756b336257a8d8b8239b7ceb451
react-native-release-profiler: 131ec5e4145d900b2be2a8d6641e2ce0dd784259
react-native-safe-area-context: 38fdd9b3c5561de7cabae64bd0cd2ce05d2768a1
react-native-view-shot: 6b7ed61d77d88580fed10954d45fad0eb2d47688
react-native-view-shot: ee44129a7c470310d3c7e67085834fc8cc077655
react-native-webview: ad29375839c9aa0409ce8e8693291b42bdc067a4
React-nativeconfig: 57781b79e11d5af7573e6f77cbf1143b71802a6d
React-NativeModulesApple: 7ff2e2cfb2e5fa5bdedcecf28ce37e696c6ef1e1
Expand Down Expand Up @@ -3246,8 +3276,8 @@ SPEC CHECKSUMS:
SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d
Turf: aa2ede4298009639d10db36aba1a7ebaad072a5e
VisionCamera: c6c8aa4b028501fc87644550fbc35a537d4da3fb
Yoga: a1d7895431387402a674fd0d1c04ec85e87909b8
Yoga: 2a45d7e59592db061217551fd3bbe2dd993817ae

PODFILE CHECKSUM: a07e55247056ec5d84d1af31d694506efff3cfe2
PODFILE CHECKSUM: 15e2f095b9c80d658459723edf84005a6867debf

COCOAPODS: 1.15.2
3 changes: 3 additions & 0 deletions jest/setup.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-disable max-classes-per-file */
import '@shopify/flash-list/jestSetup';
import type * as RNAppLogs from 'react-native-app-logs';
import 'react-native-gesture-handler/jestSetup';
import type * as RNKeyboardController from 'react-native-keyboard-controller';
import mockStorage from 'react-native-onyx/dist/storage/__mocks__';
Expand Down Expand Up @@ -75,6 +76,8 @@ jest.mock('react-native-reanimated', () => ({

jest.mock('react-native-keyboard-controller', () => require<typeof RNKeyboardController>('react-native-keyboard-controller/jest'));

jest.mock('react-native-app-logs', () => require<typeof RNAppLogs>('react-native-app-logs/jest'));

jest.mock('@src/libs/actions/Timing', () => ({
start: jest.fn(),
end: jest.fn(),
Expand Down
13 changes: 13 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@
"react-map-gl": "^7.1.3",
"react-native": "0.75.2",
"react-native-android-location-enabler": "^2.0.1",
"react-native-app-logs": "git+https://github.com/margelo/react-native-app-logs#1c183909ca2275b1fb0b2575f14ff22a36f2ff48",
"react-native-blob-util": "0.19.4",
"react-native-collapsible": "^1.6.2",
"react-native-config": "1.5.0",
Expand Down
18 changes: 18 additions & 0 deletions src/libs/Log.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

/* eslint-disable rulesdir/no-api-in-views */
import {Logger} from 'expensify-common';
import AppLogs from 'react-native-app-logs';
import Onyx from 'react-native-onyx';
import type {Merge} from 'type-fest';
import CONST from '@src/CONST';
Expand Down Expand Up @@ -82,4 +83,21 @@ const Log = new Logger({
});
timeout = setTimeout(() => Log.info('Flushing logs older than 10 minutes', true, {}, true), 10 * 60 * 1000);

AppLogs.configureAppGroupName('group.com.expensify.new');
AppLogs.registerHandler({
filter: '[NotificationService]',
kirillzyusko marked this conversation as resolved.
Show resolved Hide resolved
handler: ({filter, logs}) => {
logs.forEach((log) => {
// Both native and JS logs are captured by the filter so we replace the filter before logging to avoid an infinite loop
const message = `[PushNotification] ${log.message.replace(filter, 'NotificationService -')}`;

if (log.level === 'error') {
Log.hmmm(message);
} else {
Log.info(message);
}
});
},
});

export default Log;
Loading