Skip to content

Commit

Permalink
Merge pull request #45905 from margelo/feat/swift-logs-github
Browse files Browse the repository at this point in the history
feat: upload native logs
  • Loading branch information
arosiclair authored Oct 1, 2024
2 parents 1ff3994 + 9dfdb39 commit 8f08755
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 6 deletions.
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)
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]',
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;

0 comments on commit 8f08755

Please sign in to comment.