Skip to content

Commit 475e353

Browse files
committed
Improve macOS logging
WE2-1249 Signed-off-by: Raul Metsma <raul@metsma.ee>
1 parent 3484c81 commit 475e353

4 files changed

Lines changed: 80 additions & 14 deletions

File tree

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,22 @@ The application writes logs to
224224
- `~/Library/Containers/eu.web-eid.web-eid-safari/Data/Library/Application\ Support/RIA/web-eid-safari/web-eid-safari.log` of Safari in macOS
225225
- `C:/Users/<USER>/AppData/Local/RIA/web-eid/web-eid.log` in Windows.
226226

227+
The Safari extension and its containing app also emit structured log messages via the macOS unified logging system. To stream them live:
228+
229+
log stream --predicate 'subsystem BEGINSWITH "eu.web-eid.web-eid-safari"' --level debug
230+
231+
To query past messages (e.g. the last hour):
232+
233+
log show --predicate 'subsystem BEGINSWITH "eu.web-eid.web-eid-safari"' --last 1h
234+
235+
By default, request and response payloads are redacted in the log output. To reveal them, sign and install `src/mac/web-eid-debug-logging.mobileconfig`:
236+
237+
security cms -S -N "Apple Development: your@email.com (TEAMID)" \
238+
-i src/mac/web-eid-debug-logging.mobileconfig \
239+
-o /tmp/web-eid-debug-logging-signed.mobileconfig
240+
241+
Open the signed file — macOS will prompt to install it via System Settings → Privacy & Security → Profiles. The profile enables private data system-wide; remove it when done.
242+
227243
## Internal design
228244

229245
The Web eID native application is built with the [Qt](https://www.qt.io/) framework. It consists of

src/mac/main.mm

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,12 @@
3131

3232
#import <Cocoa/Cocoa.h>
3333
#import <SafariServices/SafariServices.h>
34+
#import <os/log.h>
3435

3536
#include "shared.hpp"
3637

38+
static os_log_t logger = os_log_create("eu.web-eid.web-eid-safari", "app");
39+
3740
#include <iostream>
3841

3942
@implementation NSApplication (MacController)
@@ -114,7 +117,7 @@ - (void)notificationEvent:(NSNotification*)notification
114117
{
115118
NSString *nonce = notification.object;
116119
NSDictionary *req = takeValue(nonce);
117-
NSLog(@"web-eid-safari: msg from extension nonce (%@) request: %@", nonce, req);
120+
os_log(logger, "msg from extension nonce (%{public}@) request: %@", nonce, req);
118121
if (req == nil) {
119122
return;
120123
}
@@ -141,7 +144,7 @@ Controller controller({
141144
}
142145
}
143146

144-
NSLog(@"web-eid-safari: msg to extension nonce (%@) request: %@", nonce, resp);
147+
os_log(logger, "msg to extension nonce (%{public}@) response: %@", nonce, resp);
145148
setValue(nonce, resp);
146149
[NSDistributedNotificationCenter.defaultCenter postNotificationName:WebEidExtension object:nonce userInfo:nil deliverImmediately:YES];
147150
QCoreApplication::quit();
@@ -174,6 +177,9 @@ int main(int argc, char* argv[])
174177
SafariApplication app(argc, argv, QStringLiteral("web-eid-safari"));
175178
auto appPtr = &app;
176179

180+
// Sender is not authenticated; DNCF is system-wide. This is intentional: the notification
181+
// is a wake-up signal only — payload is read from the App Group NSUserDefaults, which is
182+
// gated by team-ID entitlement and inaccessible to other processes.
177183
[NSDistributedNotificationCenter.defaultCenter addObserver:NSApp selector:@selector(notificationEvent:) name:WebEidApp object:nil];
178184

179185
id starting = [getUserDefaults() objectForKey:WebEidStarting];

src/mac/safari-extension.mm

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
#include "shared.hpp"
2626

2727
#import <AppKit/AppKit.h>
28+
#import <os/log.h>
29+
30+
static os_log_t logger = os_log_create("eu.web-eid.web-eid-safari.web-eid-safari-extension", "extension");
2831

2932
@interface SafariWebExtensionHandler : NSObject <NSExtensionRequestHandling> {
3033
NSMutableDictionary<NSString *, NSExtensionContext *> *contexts;
@@ -35,16 +38,19 @@ @implementation SafariWebExtensionHandler
3538

3639
- (id)init {
3740
if (self = [super init]) {
38-
NSLog(@"web-eid-safari-extension: starting");
41+
os_log(logger, "starting");
3942
contexts = [[NSMutableDictionary<NSString *, NSExtensionContext *> alloc] init];
43+
// Sender is not authenticated; DNCF is system-wide. This is intentional: the notification
44+
// is a wake-up signal only — payload is read from the App Group NSUserDefaults, which is
45+
// gated by team-ID entitlement and inaccessible to other processes.
4046
[NSDistributedNotificationCenter.defaultCenter addObserver:self selector:@selector(notificationEvent:) name:WebEidExtension object:nil];
4147
}
4248
return self;
4349
}
4450

4551
- (void)dealloc
4652
{
47-
NSLog(@"web-eid-safari-extension: stopping");
53+
os_log(logger, "stopping");
4854
[NSDistributedNotificationCenter.defaultCenter removeObserver:self name:WebEidExtension object:nil];
4955
}
5056

@@ -53,14 +59,19 @@ - (void)notificationEvent:(NSNotification*)notification
5359
// Received notification from App
5460
NSString *nonce = notification.object;
5561
NSDictionary *resp = takeValue(nonce);
56-
NSLog(@"web-eid-safari-extension: from app nonce (%@) request: %@", nonce, resp);
62+
os_log(logger, "from app nonce (%{public}@) request: %@", nonce, resp);
5763
if (resp == nil) {
5864
return;
5965
}
6066

67+
// Wait for the app to fully exit before returning the response to the page.
68+
// The app is single-shot and calls QCoreApplication::quit() after posting the response.
69+
// If we return early and the page immediately sends a follow-up request, execNativeApp
70+
// would race with the still-shutting-down instance: launchApplication may no-op against
71+
// it and the WebEidStarting handshake in Loop 1 would then time out.
6172
for (int i = 0; i < 20 && [NSRunningApplication runningApplicationsWithBundleIdentifier:WebEidApp].count > 0; ++i) {
6273
[NSThread sleepForTimeInterval:0.5];
63-
NSLog(@"web-eid-safari-extension: web-eid-safari is still running");
74+
os_log(logger, "web-eid-safari is still running");
6475
}
6576

6677
// Forward to background script
@@ -75,31 +86,31 @@ - (BOOL)execNativeApp
7586
{
7687
NSURL *appURL = [NSWorkspace.sharedWorkspace URLForApplicationWithBundleIdentifier:WebEidApp];
7788
if (appURL == nil) {
78-
NSLog(@"web-eid-safari-extension: failed to get app url");
89+
os_log_error(logger, "failed to get app url");
7990
return NO;
8091
}
8192
setValue(WebEidStarting, @(true));
8293
if (![NSWorkspace.sharedWorkspace launchApplication:appURL.path]) {
83-
NSLog(@"web-eid-safari-extension: failed to start app");
94+
os_log_error(logger, "failed to start app");
8495
return NO;
8596
}
86-
NSLog(@"web-eid-safari-extension: started app");
97+
os_log(logger, "started app");
8798
for (int i = 0; i < 20 && [getUserDefaults() boolForKey:WebEidStarting]; ++i) {
8899
[NSThread sleepForTimeInterval:0.5];
89-
NSLog(@"web-eid-safari-extension: waiting to be running %@", [getUserDefaults() objectForKey:WebEidStarting]);
100+
os_log(logger, "waiting to be running %{public}@", [getUserDefaults() objectForKey:WebEidStarting]);
90101
}
91102
if ([(NSNumber*)takeValue(WebEidStarting) boolValue]) {
92-
NSLog(@"web-eid-safari-extension: timeout to start app");
103+
os_log_error(logger, "timeout to start app");
93104
return NO;
94105
}
95-
NSLog(@"web-eid-safari-extension: app executed");
106+
os_log(logger, "app executed");
96107
return YES;
97108
}
98109

99110
- (void)beginRequestWithExtensionContext:(NSExtensionContext*)context
100111
{
101112
id message = [context.inputItems.firstObject userInfo][SFExtensionMessageKey];
102-
NSLog(@"web-eid-safari-extension: msg from background.js %@", message);
113+
os_log(logger, "msg from background.js %@", message);
103114

104115
if ([@"status" isEqualToString:message[@"command"]]) {
105116
NSString *version = [NSString stringWithFormat:@"%@+%@",
@@ -119,7 +130,7 @@ - (void)beginRequestWithExtensionContext:(NSExtensionContext*)context
119130
return;
120131
}
121132

122-
NSLog(@"web-eid-safari-extension: sending message to app %@", message);
133+
os_log(logger, "sending message to app %@", message);
123134

124135
// Save context
125136
NSString *nonce = [[[NSUUID alloc] init] UUIDString];
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>PayloadContent</key>
6+
<array>
7+
<dict>
8+
<key>PayloadType</key>
9+
<string>com.apple.system.logging</string>
10+
<key>PayloadIdentifier</key>
11+
<string>eu.web-eid.web-eid-safari.logging</string>
12+
<key>PayloadUUID</key>
13+
<string>4F8A1B2C-3D4E-5F6A-7B8C-9D0E1F2A3B4C</string>
14+
<key>PayloadVersion</key>
15+
<integer>1</integer>
16+
<key>Enable-Private-Data</key>
17+
<true/>
18+
</dict>
19+
</array>
20+
<key>PayloadDisplayName</key>
21+
<string>web-eid Debug Logging</string>
22+
<key>PayloadDescription</key>
23+
<string>Enables private data in os_log output system-wide. Install for debugging only; remove when done.</string>
24+
<key>PayloadIdentifier</key>
25+
<string>eu.web-eid.debug-logging-profile</string>
26+
<key>PayloadType</key>
27+
<string>Configuration</string>
28+
<key>PayloadUUID</key>
29+
<string>5A9B2C3D-4E5F-6A7B-8C9D-0E1F2A3B4C5D</string>
30+
<key>PayloadVersion</key>
31+
<integer>1</integer>
32+
</dict>
33+
</plist>

0 commit comments

Comments
 (0)