Skip to content

Instantly share code, notes, and snippets.

@kristopherjohnson
Last active November 6, 2020 05:59
Show Gist options
  • Select an option

  • Save kristopherjohnson/0ded6cd153f61c627226 to your computer and use it in GitHub Desktop.

Select an option

Save kristopherjohnson/0ded6cd153f61c627226 to your computer and use it in GitHub Desktop.
Demo of using the Apple System Log (ASL) API from Swift
// Note: This must be used in an Xcode project that contains a bridging header
// that includes <asl.h>
import Foundation
/// Provides high-level methods to access the raw data in
/// an ASL message.
struct SystemLogEntry {
/// Key-value pairs read from ASL message
let data: [String : String]
init(_ data: [String : String]) {
self.data = data
}
var time: String { return data[ASL_KEY_TIME] ?? "" }
var timeNanoSec: String { return data[ASL_KEY_TIME_NSEC] ?? "" }
var host: String { return data[ASL_KEY_HOST] ?? "" }
var sender: String { return data[ASL_KEY_SENDER] ?? "" }
var facility: String { return data[ASL_KEY_FACILITY] ?? "" }
var PID: String { return data[ASL_KEY_PID] ?? "" }
var UID: String { return data[ASL_KEY_UID] ?? "" }
var GID: String { return data[ASL_KEY_GID] ?? "" }
var level: String { return data[ASL_KEY_LEVEL] ?? "" }
var message: String { return data[ASL_KEY_MSG] ?? "" }
var readUID: String { return data[ASL_KEY_READ_UID] ?? "" }
var readGID: String { return data[ASL_KEY_READ_GID] ?? "" }
var expireTime: String { return data[ASL_KEY_EXPIRE_TIME] ?? "" }
var messageID: String { return data[ASL_KEY_MSG_ID] ?? "" }
var session: String { return data[ASL_KEY_SESSION] ?? "" }
var refPID: String { return data[ASL_KEY_REF_PID] ?? "" }
var refProc: String { return data[ASL_KEY_REF_PROC] ?? "" }
var auxTitle: String { return data[ASL_KEY_AUX_TITLE] ?? "" }
var auxUTI: String { return data[ASL_KEY_AUX_UTI] ?? "" }
var auxURL: String { return data[ASL_KEY_AUX_URL] ?? "" }
var option: String { return data[ASL_KEY_OPTION] ?? "" }
var module: String { return data[ASL_KEY_MODULE] ?? "" }
var senderInstance: String { return data[ASL_KEY_SENDER_INSTANCE] ?? "" }
var senderMachUUID: String { return data[ASL_KEY_SENDER_MACH_UUID] ?? "" }
var finalNotification: String { return data[ASL_KEY_FINAL_NOTIFICATION] ?? "" }
var OSActivityID: String { return data[ASL_KEY_OS_ACTIVITY_ID] ?? "" }
/// Get the entry time as an NSDate
var date: NSDate {
var sec = time.toInt() ?? 0
var nanosec = timeNanoSec.toInt() ?? 0
var timeInterval = NSTimeInterval(sec) + NSTimeInterval(nanosec) * 1.0e-9
return NSDate(timeIntervalSince1970: timeInterval)
}
/// Get the level as a displayable string
var levelDescription: String {
if let levelAsInt = level.toInt() {
switch Int32(levelAsInt) {
case ASL_LEVEL_EMERG: return ASL_STRING_EMERG
case ASL_LEVEL_ALERT: return ASL_STRING_ALERT
case ASL_LEVEL_CRIT: return ASL_STRING_CRIT
case ASL_LEVEL_ERR: return ASL_STRING_ERR
case ASL_LEVEL_WARNING: return ASL_STRING_WARNING
case ASL_LEVEL_NOTICE: return ASL_STRING_NOTICE
case ASL_LEVEL_INFO: return ASL_STRING_INFO
case ASL_LEVEL_DEBUG: return ASL_STRING_DEBUG
default: return "Unknown"
}
}
else {
return "Unknown"
}
}
}
struct SystemLog {
/// Invoke a specified closure for every entry in the system log
///
/// The closure argument is a dictionary where each key
/// is a message attribute name, and the value is the
/// value of that attribute.
static func readAllLogEntries(processLogEntry: (SystemLogEntry) -> ()) {
let query = asl_new(UInt32(ASL_TYPE_QUERY))
let response = asl_search(nil, query)
for var msg = asl_next(response); msg != nil; msg = asl_next(response) {
var dict: [String : String] = [:]
var keyIndex = UInt32(0)
for var key = asl_key(msg, keyIndex); key != nil; key = asl_key(msg, ++keyIndex) {
if let keyString = String.fromCString(key) {
let value = asl_get(msg, key)
let valueString = (value == nil) ? "" : String.fromCString(value)
dict[keyString] = valueString ?? ""
}
}
let logEntry = SystemLogEntry(dict)
processLogEntry(logEntry)
}
asl_release(response)
}
}
@kristopherjohnson

Copy link
Copy Markdown
Author

Example use:

// Print all log entries
var dateFormatter = NSDateFormatter()
dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss.SSS"
SystemLog.readAllLogEntries { entry in
    let timestamp = dateFormatter.stringFromDate(entry.date)
    println("\(timestamp) [\(entry.PID)] \(entry.levelDescription): \(entry.message)")
}

@neil-wu

neil-wu commented Aug 25, 2015

Copy link
Copy Markdown

Can not get log on ios8 device?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment