aboutsummaryrefslogtreecommitdiffstats
path: root/WireGuard/Shared/Logging/Logger.swift
blob: f8ef70a78c1f7a43370acc28328245811ddc03fa (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// SPDX-License-Identifier: MIT
// Copyright © 2018 WireGuard LLC. All Rights Reserved.

import Foundation
import os.log

public class Logger {
    static var global: Logger?

    var log: OpaquePointer?
    var tag: String

    init(withFilePath filePath: String, withTag tag: String) {
        self.tag = tag
        self.log = filePath.withCString { fileC -> OpaquePointer? in
            open_log(fileC)
        }
        if self.log == nil {
            os_log("Cannot open log file for writing. Log will not be saved to file.", log: OSLog.default, type: .error)
        }
    }

    func log(message: String) {
        guard let log = log else { return }
        String(format: "[%@] %@", tag, message.trimmingCharacters(in: .newlines)).withCString { messageC in
            write_msg_to_log(log, messageC)
        }
    }

    func writeLog(mergedWith otherLogFile: String, to targetFile: String) -> Bool {
        guard let log = log else { return false }
        guard let other = otherLogFile.withCString({ otherC -> OpaquePointer? in
            return open_log(otherC)
        }) else { return false }
        defer { close_log(other) }
        return targetFile.withCString { fileC -> Bool in
            return write_logs_to_file(fileC, log, other) == 0
        }
    }

    static func configureGlobal(withFilePath filePath: String?, withTag tag: String) {
        if Logger.global != nil {
            return
        }
        guard let filePath = filePath else {
            os_log("Unable to determine log destination path. Log will not be saved to file.", log: OSLog.default, type: .error)
            return
        }
        Logger.global = Logger(withFilePath: filePath, withTag: tag)
        var appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "Unknown version"
        if let appBuild = Bundle.main.infoDictionary?["CFBundleVersion"] as? String {
            appVersion += " (\(appBuild))"
        }
        let goBackendVersion = WIREGUARD_GO_VERSION
        Logger.global?.log(message: "App version: \(appVersion); Go backend version: \(goBackendVersion)")

    }
}

func wg_log(_ type: OSLogType, staticMessage msg: StaticString) {
    os_log(msg, log: OSLog.default, type: type)
    Logger.global?.log(message: "\(msg)")
}

func wg_log(_ type: OSLogType, message msg: String) {
    os_log("%{public}s", log: OSLog.default, type: type, msg)
    Logger.global?.log(message: msg)
}