Skip to content

Commit

Permalink
Nr 318119 auto collect stdout & stderr logs (#320)
Browse files Browse the repository at this point in the history
* NR-318119 adding the ability to collect the logs sent to stdout and stderr

* NR-318119 added a way to extract type of OSLog and fixed timestamp format

* Removed unneeded test

* NR-318119 Renamed the flag to include stderr and changed the log divider to \n\n

* Trying to get more accurate timestamps when one's not there

* Changed the log collector to use a pipe and added a unit test

* Restoring the logging sooner in the test to hopefully see failed test logs

* Trying to fix a test that only fails on github

* trying to fix test run on github

* It looks like github unit tests don't have oslog debug enabled

* Looks like this test doesn't work on github for watchOS, will need to look further into it

* Unit test changes

* Restoring the first delay in the test

* Trying to make the test less flakey

* Using sleep instead of the wait

* Adjusting the sleep value

* We need default priority or the collected logs don't maintain perfect accuracy

* NRLogger: Fix to honor remote log level and local log level correctly.

* Revert "NRLogger: Fix to honor remote log level and local log level correctly."

This reverts commit 28790a5.

* Changing the name and default status of the feature flag, only redirect if remote logging is enabled

* Forgot to change flag in unit tests

* Added a stress test WIP, created the pipes one at a time so we can close them if needed

* Removed the feature flag and only capture logs when the debugger isn't attached

* Updating the Xcode version used in main.yml

* trying to update to macos-14 in main.yml

* trying xcode 15.4

* Changed the requiredAttributes to work with the auto-collected logs better

* Added back the feature flag after discussion

* Update Agent/Utilities/NRLogger.m

Co-authored-by: Chris Dillard <[email protected]>

---------

Co-authored-by: Chris Dillard <[email protected]>
Co-authored-by: Chris Dillard <[email protected]>
  • Loading branch information
3 people authored Nov 22, 2024
1 parent 2fb2fd6 commit e31d8d4
Show file tree
Hide file tree
Showing 17 changed files with 556 additions and 27 deletions.
12 changes: 6 additions & 6 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ jobs:
name : TestIOS
# runs-on: will be set to macos-latest when running on actual GHA.
# *** runs-on: ubuntu-latest is used when running via act on mac os. ***
runs-on: macos-13
runs-on: macos-14
steps:
- uses: actions/checkout@master
with:
submodules: true

- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: '14.3'
xcode-version: '15.4'

- name: Install lcov
run: |
Expand Down Expand Up @@ -52,7 +52,7 @@ jobs:

- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: '14.3'
xcode-version: '15.4'

- name: Install lcov
run: brew install lcov
Expand All @@ -78,7 +78,7 @@ jobs:

- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: '14.3'
xcode-version: '15.4'

- name: Install lcov
run: brew install lcov
Expand All @@ -96,7 +96,7 @@ jobs:
name: DeployS3
# runs-on: will be set to macos-latest when running on actual GHA.
# *** runs-on: ubuntu-latest is used when running via act on mac os. ***
runs-on: macos-13
runs-on: macos-14
needs: [testIOS, testTVOS, testWatchOS]
if: github.ref == 'refs/heads/staging' || github.ref == 'refs/heads/main'
outputs:
Expand All @@ -108,7 +108,7 @@ jobs:

- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: '14.3'
xcode-version: '15.4'

- name: Install the Apple certificate and provisioning profile
env:
Expand Down
28 changes: 28 additions & 0 deletions Agent.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1497,12 +1497,16 @@
F858F3602AE04B0C00CF9EB5 /* NRMAURLSessionHeaderTrackingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F858F35F2AE04B0C00CF9EB5 /* NRMAURLSessionHeaderTrackingTests.m */; };
F858F3612AE04B0C00CF9EB5 /* NRMAURLSessionHeaderTrackingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F858F35F2AE04B0C00CF9EB5 /* NRMAURLSessionHeaderTrackingTests.m */; };
F86741072BD30F3F00DAA1A2 /* NRMAExceptionDataCollectionWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 02FF48D024DC622400115469 /* NRMAExceptionDataCollectionWrapper.m */; };
F8678AAE2CDBC62B008FD2A2 /* NRAutoCollectLogStressTest.m in Sources */ = {isa = PBXBuildFile; fileRef = F8678AAC2CDBC62B008FD2A2 /* NRAutoCollectLogStressTest.m */; };
F8728E412ACC9D5A0056F641 /* NRMANetworkMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = F8728E402ACC9D5A0056F641 /* NRMANetworkMonitor.m */; };
F8728E422ACC9D5A0056F641 /* NRMANetworkMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = F8728E402ACC9D5A0056F641 /* NRMANetworkMonitor.m */; };
F87954D529E89D5F00319FCD /* NRMAWKWebViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0209ABB324E704A600E45C90 /* NRMAWKWebViewTests.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
F88C2CF72A2FA7AC00373EFE /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = F88C2CE32A2FA7AC00373EFE /* PrivacyInfo.xcprivacy */; };
F89167372BC9D1270085BCFC /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = F88C2CE32A2FA7AC00373EFE /* PrivacyInfo.xcprivacy */; };
F89167442BCD8EA30085BCFC /* NRViewModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = F824A43029AEAD63000886A6 /* NRViewModifier.swift */; };
F891A6BE2CB6F5C1007675F4 /* NRAutoLogCollector.m in Sources */ = {isa = PBXBuildFile; fileRef = F891A6BD2CB6F5C1007675F4 /* NRAutoLogCollector.m */; };
F891A6BF2CB6F5C1007675F4 /* NRAutoLogCollector.m in Sources */ = {isa = PBXBuildFile; fileRef = F891A6BD2CB6F5C1007675F4 /* NRAutoLogCollector.m */; };
F891A6C02CB6F5C1007675F4 /* NRAutoLogCollector.m in Sources */ = {isa = PBXBuildFile; fileRef = F891A6BD2CB6F5C1007675F4 /* NRAutoLogCollector.m */; };
F8A455482AFBE31E0057B1E0 /* NRMAURLSessionHeaderTrackingTestsOldEventSystem.m in Sources */ = {isa = PBXBuildFile; fileRef = F8A455472AFBE31E0057B1E0 /* NRMAURLSessionHeaderTrackingTestsOldEventSystem.m */; };
F8A455492AFBE31E0057B1E0 /* NRMAURLSessionHeaderTrackingTestsOldEventSystem.m in Sources */ = {isa = PBXBuildFile; fileRef = F8A455472AFBE31E0057B1E0 /* NRMAURLSessionHeaderTrackingTestsOldEventSystem.m */; };
F8AC3E932938FD6C002B4AA8 /* NRMAFakeDataHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = F8AC3E922938FD6C002B4AA8 /* NRMAFakeDataHelper.m */; };
Expand Down Expand Up @@ -2465,10 +2469,13 @@
F848CDBF2AA133EA0082052F /* NRMAInteractionEvent.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NRMAInteractionEvent.m; sourceTree = "<group>"; };
F848CDD52AA133FB0082052F /* NRMAInteractionEvent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NRMAInteractionEvent.h; sourceTree = "<group>"; };
F858F35F2AE04B0C00CF9EB5 /* NRMAURLSessionHeaderTrackingTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NRMAURLSessionHeaderTrackingTests.m; sourceTree = "<group>"; };
F8678AAC2CDBC62B008FD2A2 /* NRAutoCollectLogStressTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NRAutoCollectLogStressTest.m; sourceTree = "<group>"; };
F8728E402ACC9D5A0056F641 /* NRMANetworkMonitor.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NRMANetworkMonitor.m; sourceTree = "<group>"; };
F8728E562ACC9F840056F641 /* NRMANetworkMonitor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NRMANetworkMonitor.h; sourceTree = "<group>"; };
F88C2CE32A2FA7AC00373EFE /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
F89167382BC9D1540085BCFC /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "Platforms/WatchOS.platform/Developer/SDKs/WatchOS10.2.sdk/usr/lib/libc++.tbd"; sourceTree = DEVELOPER_DIR; };
F891A6BD2CB6F5C1007675F4 /* NRAutoLogCollector.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NRAutoLogCollector.m; sourceTree = "<group>"; };
F891A6D42CB6F5D8007675F4 /* NRAutoLogCollector.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NRAutoLogCollector.h; sourceTree = "<group>"; };
F8A455472AFBE31E0057B1E0 /* NRMAURLSessionHeaderTrackingTestsOldEventSystem.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NRMAURLSessionHeaderTrackingTestsOldEventSystem.m; sourceTree = "<group>"; };
F8AC3E922938FD6C002B4AA8 /* NRMAFakeDataHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NRMAFakeDataHelper.m; sourceTree = "<group>"; };
F8AC3EA72938FDDB002B4AA8 /* NRMAFakeDataHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NRMAFakeDataHelper.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3006,6 +3013,7 @@
025658AC24EB2AAC00FE3125 /* Info.plist */,
025658D624EB322F00FE3125 /* NRMAStressTestHelper.h */,
025658D724EB322F00FE3125 /* NRMAStressTestHelper.m */,
F8678AAD2CDBC62B008FD2A2 /* Logging Stress Tests */,
025658C524EB2F3300FE3125 /* Measurement Engine Stress Tests */,
025658C224EB2EF300FE3125 /* Harvester Stress Tests */,
025658BD24EB2ED900FE3125 /* Analytics Stress Tests */,
Expand Down Expand Up @@ -3641,6 +3649,8 @@
02FF4A8924DC652D00115469 /* NewRelicInternalUtils.h */,
02FF4A9024DC652D00115469 /* NewRelicInternalUtils.m */,
02FF4A7E24DC652B00115469 /* NRLogger.m */,
F891A6D42CB6F5D8007675F4 /* NRAutoLogCollector.h */,
F891A6BD2CB6F5C1007675F4 /* NRAutoLogCollector.m */,
02FF4A8224DC652C00115469 /* NRMAAppToken.h */,
02FF4A8E24DC652D00115469 /* NRMAAppToken.m */,
02FF4A8724DC652C00115469 /* NRMABase64.h */,
Expand Down Expand Up @@ -3867,6 +3877,14 @@
path = "DistributedTesting-Tests";
sourceTree = "<group>";
};
F8678AAD2CDBC62B008FD2A2 /* Logging Stress Tests */ = {
isa = PBXGroup;
children = (
F8678AAC2CDBC62B008FD2A2 /* NRAutoCollectLogStressTest.m */,
);
path = "Logging Stress Tests";
sourceTree = "<group>";
};
F8FBFA3C2A71A32400CDC8C5 /* Events */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -5388,6 +5406,7 @@
02FF48F424DC623400115469 /* NRMAExceptionMetaDataStore.m in Sources */,
02FF4A2124DC648600115469 /* NRMASummaryMeasurementConsumer.m in Sources */,
02FF482924DB5BA500115469 /* NRMAFlags.m in Sources */,
F891A6BE2CB6F5C1007675F4 /* NRAutoLogCollector.m in Sources */,
02FF48D924DC622700115469 /* NRMACrashDataWriter.m in Sources */,
02FF487224DC618F00115469 /* NRGCDOverride.m in Sources */,
02FF494D24DC626E00115469 /* NRMAHarvesterConnection.m in Sources */,
Expand Down Expand Up @@ -5532,6 +5551,7 @@
025658C124EB2EE900FE3125 /* NRMAAnalyticsControllerStressor.m in Sources */,
025658CF24EB2F5B00FE3125 /* NRMAMeasurementProducerStressor.m in Sources */,
025658C424EB2F3100FE3125 /* NRMAHarvestControllerStressor.m in Sources */,
F8678AAE2CDBC62B008FD2A2 /* NRAutoCollectLogStressTest.m in Sources */,
025658D524EB2F6400FE3125 /* NRMAActivityTraceMeasurementCreatorStressor.m in Sources */,
025658DD24EB350300FE3125 /* NRAgentTestBase.m in Sources */,
025658D424EB2F6400FE3125 /* NRMASummaryMeasurementConsumerStressor.m in Sources */,
Expand All @@ -5558,6 +5578,7 @@
02FF4BF424E3201400115469 /* NRMAScopedHTTPTransactionMeasurement.m in Sources */,
02FF4BF524E3201400115469 /* NRMAMethodSwizzling.m in Sources */,
02FF4BF624E3201400115469 /* NRMACrashReporterRecorder.m in Sources */,
F891A6BF2CB6F5C1007675F4 /* NRAutoLogCollector.m in Sources */,
02FF4BF724E3201400115469 /* NRMACrashReport_CodeType.m in Sources */,
02FF4BF824E3201400115469 /* NRMAHarvestableHTTPTransaction.m in Sources */,
02FF4BF924E3201400115469 /* NRMAHarvestableActivity.m in Sources */,
Expand Down Expand Up @@ -5917,6 +5938,7 @@
3482325C2BC5F16E0070FAC3 /* NRMACPUVitals.m in Sources */,
348232502BC5F14D0070FAC3 /* NRMADEBUG_Reachability.m in Sources */,
348233532BC5F2780070FAC3 /* NRMAThread.m in Sources */,
F891A6C02CB6F5C1007675F4 /* NRAutoLogCollector.m in Sources */,
3482325D2BC5F16E0070FAC3 /* NRMABool.m in Sources */,
348233212BC5F2270070FAC3 /* NRMACrashReport_CodeType.m in Sources */,
3482328B2BC5F1B30070FAC3 /* NRMAMetric.m in Sources */,
Expand Down Expand Up @@ -6587,16 +6609,19 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ARCHS = "$(ARCHS_STANDARD)";
CLANG_ENABLE_CODE_COVERAGE = YES;
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 7.5.3;
DEVELOPMENT_TEAM = SU7SUNGZJP;
DYLIB_CURRENT_VERSION = 7.5.3;
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/Frameworks";
HEADER_SEARCH_PATHS = (
"${PROJECT_DIR}/UnitTests/",
"${SRCROOT}/**",
);
INFOPLIST_FILE = "Tests/Stress-Tests/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down Expand Up @@ -6626,16 +6651,19 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ARCHS = "$(ARCHS_STANDARD)";
CLANG_ENABLE_CODE_COVERAGE = YES;
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 7.5.3;
DEVELOPMENT_TEAM = SU7SUNGZJP;
DYLIB_CURRENT_VERSION = 7.5.3;
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/Frameworks";
HEADER_SEARCH_PATHS = (
"${PROJECT_DIR}/UnitTests/",
"${SRCROOT}/**",
);
INFOPLIST_FILE = "Tests/Stress-Tests/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down
2 changes: 2 additions & 0 deletions Agent/FeatureFlags/NRMAFlags.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@

+ (BOOL) shouldEnableBackgroundReporting;

+ (BOOL) shouldEnableAutoCollectLogs;

+ (NSArray<NSString*>*) namesForFlags:(NRMAFeatureFlags)flags;

// Private Setting
Expand Down
10 changes: 9 additions & 1 deletion Agent/FeatureFlags/NRMAFlags.m
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ + (NRMAFeatureFlags) featureFlags
NRFeatureFlag_NetworkRequestEvents |
NRFeatureFlag_RequestErrorEvents |
NRFeatureFlag_DistributedTracing |
NRFeatureFlag_AppStartMetrics;
NRFeatureFlag_AppStartMetrics |
NRFeatureFlag_AutoCollectLogs;
});
return __flags;
}
Expand Down Expand Up @@ -177,6 +178,10 @@ + (BOOL) shouldEnableBackgroundReporting {
return ([NRMAFlags featureFlags] & NRFeatureFlag_BackgroundReporting) != 0;
}

+ (BOOL) shouldEnableAutoCollectLogs {
return ([NRMAFlags featureFlags] & NRFeatureFlag_AutoCollectLogs) != 0;
}

+ (NSArray<NSString*>*) namesForFlags:(NRMAFeatureFlags)flags {
NSMutableArray *retArray = [NSMutableArray array];
if ((flags & NRFeatureFlag_InteractionTracing) == NRFeatureFlag_InteractionTracing) {
Expand Down Expand Up @@ -239,6 +244,9 @@ + (BOOL) shouldEnableBackgroundReporting {
if ((flags & NRFeatureFlag_BackgroundReporting) == NRFeatureFlag_BackgroundReporting) {
[retArray addObject:@"BackgroundReporting"];
}
if ((flags & NRFeatureFlag_AutoCollectLogs) == NRFeatureFlag_AutoCollectLogs) {
[retArray addObject:@"AutoCollectLogs"];
}

return retArray;
}
Expand Down
1 change: 1 addition & 0 deletions Agent/General/NewRelicAgentInternal.m
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
#import "NRMAStartTimer.h"
#import "NRMAUDIDManager.h"
#import "NRMASupportMetricHelper.h"
#import "NRAutoLogCollector.h"


// Support for teardown and re-setup of the agent within a process lifetime for our test harness
Expand Down
16 changes: 13 additions & 3 deletions Agent/Harvester/NRMAHarvester.mm
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#import "NRMAFlags.h"
#import "Constants.h"
#import "NewRelicAgentInternal.h"
#import "NewRelicInternalUtils.h"
#import "NRAutoLogCollector.h"

#define kNRSupportabilityResponseCode kNRSupportabilityPrefix @"/Collector/ResponseStatusCodes"

Expand Down Expand Up @@ -772,9 +774,14 @@ - (void) handleLoggingConfigurationUpdate {
// This if/else chain should only be entered if log_reporting was found in the config
if (configuration.has_log_reporting_config) {
if (configuration.log_reporting_enabled) {

// it is required to enable NRLogTargetFile when using LogReporting.
[NRLogger setLogTargets:NRLogTargetConsole | NRLogTargetFile];
if ([NRMAFlags shouldEnableAutoCollectLogs] && ![NewRelicInternalUtils isDebuggerAttached]){
[NRAutoLogCollector redirectStandardOutputAndError];
// it is required to enable NRLogTargetFile when using LogReporting.
[NRLogger setLogTargets:NRLogTargetFile];
} else {
[NRLogger setLogTargets:NRLogTargetConsole | NRLogTargetFile];
}

// Parse NSString into NRLogLevel
NRLogLevels level = [NRLogger stringToLevel: configuration.log_reporting_level];
[NRLogger setRemoteLogLevel:level];
Expand All @@ -786,6 +793,9 @@ - (void) handleLoggingConfigurationUpdate {
// OVERWRITE user selected value for LogReporting.
else {
NRLOG_AGENT_DEBUG(@"config: Has log reporting DISABLED");
if ([NRMAFlags shouldEnableAutoCollectLogs]) {
[NRAutoLogCollector restoreStandardOutputAndError];
}
[NRLogger setLogTargets:NRLogTargetConsole];

[NRMAFlags disableFeatures:NRFeatureFlag_LogReporting];
Expand Down
4 changes: 4 additions & 0 deletions Agent/Public/NRLogger.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ withAttributes:(NSDictionary *)attributes;
withMessage:(NSString *)message
withAgentLogsOn:(BOOL)agentLogsOn;

+ (void) log:(unsigned int)level
withMessage:(NSString *)message
withTimestamp:(NSNumber *)timestamp;

/*!
Configure the amount of information the New Relic agent outputs about its internal operation.
Expand Down
2 changes: 1 addition & 1 deletion Agent/Public/NewRelicFeatureFlags.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,5 +102,5 @@ typedef NS_OPTIONS(unsigned long long, NRMAFeatureFlags){
NRFeatureFlag_NewEventSystem = 1 << 20, // Disabled by default
NRFeatureFlag_OfflineStorage = 1 << 21, // Disabled by default
NRFeatureFlag_BackgroundReporting = 1 << 22, // Disabled by default

NRFeatureFlag_AutoCollectLogs = 1 << 23,
};
20 changes: 20 additions & 0 deletions Agent/Utilities/NRAutoLogCollector.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// NRAutoLogCollector.h
// Agent
//
// Created by Mike Bruin on 10/9/24.
// Copyright © 2024 New Relic. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface NRAutoLogCollector : NSObject {


}

+ (BOOL) redirectStandardOutputAndError;
+ (void) restoreStandardOutputAndError;
+ (BOOL) hasRedirectedStdOut;

@end
Loading

0 comments on commit e31d8d4

Please sign in to comment.