8 Years later this has not been solved right? I'm also currently looking at this issue and can't figure out how to evaluate the incoming attachments value. Any progress here?
Post
Replies
Boosts
Views
Activity
I want to express my gratitude for your detailed response and the effort you put into addressing my previous query. Your input is highly appreciated! :D
I implemented your provided code in a new project by simply copying and pasting it. This code offers a straightforward UI for triggering various logging events, making it easy to test different scenarios.
//
// ContentView.swift
// LoggingTest
//
import SwiftUI
import OSLog
struct ContentView: View {
@StateObject private var loggerModel = LoggerModel()
var body: some View {
VStack {
Spacer()
HStack {
VStack {
Text("Stdout Counter")
Text("\(loggerModel.stdoutCount)")
}
VStack {
Text("Stderr Counter")
Text("\(loggerModel.stderrCount)")
}
}
Spacer()
Button("printToStdout") {
loggerModel.printToStdout()
}
Button("printToStderr") {
loggerModel.printToStderr()
}
Button("logWithLogger") {
loggerModel.logWithLogger()
}
Spacer()
}
.padding()
}
}
//
// LoggerModel.swift
// LoggingTest
//
import Foundation
import OSLog
import System
final class LoggerModel: ObservableObject {
@Published var stdoutCount: Int = 0
@Published var stderrCount: Int = 0
var pipeStdoutQ: Pipe? = nil
var pipeStderrQ: Pipe? = nil
init() {
hookStdoutAndStderr()
}
func hookStdoutAndStderr() {
func hook(_ fd: FileDescriptor, _ accumulate: @escaping (Int) -> Void) -> Pipe {
let pipe = Pipe()
let write = FileDescriptor(rawValue: pipe.fileHandleForWriting.fileDescriptor)
_ = try! write.duplicate(as: fd)
pipe.fileHandleForReading.readabilityHandler = { fh in
let count = fh.availableData.count
DispatchQueue.main.async {
accumulate(count)
}
}
return pipe
}
self.pipeStdoutQ = hook(.standardOutput, { self.stdoutCount += $0 })
self.pipeStderrQ = hook(.standardError, { self.stderrCount += $0 })
}
func printToStdout() {
let msg = "stdout says Hello Cruel World! \(Date())\n"
write(STDOUT_FILENO, msg, msg.utf8.count)
}
func printToStderr() {
let msg = "stderr says Goodbye Cruel World! \(Date())\n"
write(STDERR_FILENO, msg, msg.utf8.count)
}
let log = Logger(subsystem: "com.example.apple-samplecode.Test739047", category: "app")
func logWithLogger() {
log.log("Logger says Hello Cruel World! \(Date())")
}
}
My observations on iPadOS 16.7 are as follows:
When launching the app via the Xcode debugger:
App starts with Stdout Counter and Stderr Counter of 0.
I tap on printToStdout and launch printToStdout --> Stdout Counter has a counter of 57.
I tap on printToStderr and launch printToStderr --> Stderr Counter has a counter of 59.
I tap on logWithLogger and launch logWithLogger --> Stderr Counter has a counter of 180.
However, when the app is terminated and relaunched directly from the home screen:
App starts with Stdout Counter and Stderr Counter of 0.
I tap on printToStdout and launch printToStdout --> Stdout Counter has a counter of 57.
I tap on printToStderr and launch printToStderr --> Stderr Counter has a counter of 59.
I tap on logWithLogger and launch logWithLogger --> Stderr Counter stays at 59.
After these results, I had to double-check again on my project to see if my findings are correct based on my recent comment.
And it truly seems like I, my findings were wrong. Sorry on my behalf for wasting your time :/
Based on both observations, it appears that, for the readabilityHandler to be triggered (outside of debugging), the low-level write() API is the way to go.
My questions are now the following:
Why is it logged when using the debugger but outside (starting from the home screen) the logs coming from Logger are not invoking readabilityHandler?
Is there a more Swift-friendly approach to writing logs to a file, or if this method is discouraged, and if so, what alternatives might be recommended for collecting log files.
Thank you once again for your invaluable assistance and patience in addressing this matter. Your insights are greatly appreciated.
And apologize again for any confusions :/
I forgot to mention, that I cannot verify what logging API this framework is using, since it's a proprietary framework and they deliver it to us as already compiled binary.
Okay, so the following is happening on iOS 16 and works as expected:
I have code that creates two pipes (one for input and one for output).
Using dup2 redirect data sent to output to stderr
Using dup2 redirect data sent to stderr to input
It monitors the input using FileHandle, writing the results to a file.
I leave this installed in my release build
When I run the app from the Home screen, the resulting file does contain log entries I wrote using Logger
It also does contain log entries written by other framework running in my process.
On iOS 16 when debugging:
Code still the same
It monitors the input using FileHandle, writing the results to a file.
I start the app using Xcode and debug it on a simulator/device
The resulting file does contain log entries I wrote using Logger
It also does contain log entries written by other framework running in my process.
So basically on iOS 16 it works flawless.
Now...
On iOS 17 when running in release:
Code still the same
It monitors the input using FileHandle, writing the results to a file.
I leave this installed in my release build
When I run the app from the Home screen, the resulting file does not contain log entries I wrote using Logger
But it does contain log entries written by other framework running in my process.
On iOS 17 when running in debug:
Code still the same
It monitors the input using FileHandle, writing the results to a file.
I start the app using Xcode and debug it on a simulator/device
The resulting file does not contain log entries I wrote using Logger
It also does not contain log entries written by other framework running in my process.
Great question! During debugging, the readabilityHandler isn't invoked (which isn't an issue as we can view logs in Xcode 15's new debug console). When running the app normally, the readabilityHandler is only invoked sporadically. To clarify, our logs (using Logger) aren't captured, while those from other frameworks do trigger the readabilityHandler.