Logging: Use ringlogger for logging from the extension
This commit is contained in:
parent
0a482470bb
commit
3520ad13e7
|
@ -14,7 +14,15 @@ extension FileManager {
|
||||||
os_log("Can't obtain shared folder URL", log: OSLog.default, type: .error)
|
os_log("Can't obtain shared folder URL", log: OSLog.default, type: .error)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return sharedFolderURL.appendingPathComponent("last-activated-tunnel-log.txt")
|
return sharedFolderURL.appendingPathComponent("tunnel-log.txt")
|
||||||
|
}
|
||||||
|
|
||||||
|
static var appLogFileURL: URL? {
|
||||||
|
guard let documentDirURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
|
||||||
|
os_log("Can't obtain app documents folder URL", log: OSLog.default, type: .error)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return documentDirURL.appendingPathComponent("app-log.txt")
|
||||||
}
|
}
|
||||||
|
|
||||||
static func deleteFile(at url: URL) -> Bool {
|
static func deleteFile(at url: URL) -> Bool {
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
// Copyright © 2018 WireGuard LLC. All Rights Reserved.
|
||||||
|
|
||||||
|
import os.log
|
||||||
|
|
||||||
|
class Logger {
|
||||||
|
static var logPtr: UnsafeMutablePointer<log>?
|
||||||
|
|
||||||
|
static func configure(withFilePath filePath: String) -> Bool {
|
||||||
|
let logPtr = filePath.withCString { filePathCStr -> UnsafeMutablePointer<log>? in
|
||||||
|
return open_log(filePathCStr)
|
||||||
|
}
|
||||||
|
Logger.logPtr = logPtr
|
||||||
|
return (logPtr != nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func writeLog(mergedWith otherLogFile: String, to targetFile: String) -> Bool {
|
||||||
|
let otherlogPtr = otherLogFile.withCString { otherLogFileCStr -> UnsafeMutablePointer<log>? in
|
||||||
|
return open_log(otherLogFileCStr)
|
||||||
|
}
|
||||||
|
if let thisLogPtr = Logger.logPtr, let otherlogPtr = otherlogPtr {
|
||||||
|
return targetFile.withCString { targetFileCStr -> Bool in
|
||||||
|
let returnValue = write_logs_to_file(targetFileCStr, thisLogPtr, otherlogPtr)
|
||||||
|
return (returnValue == 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func wg_log(_ type: OSLogType, staticMessage msg: StaticString) {
|
||||||
|
// Write to os log
|
||||||
|
os_log(msg, log: OSLog.default, type: type)
|
||||||
|
// Write to file log
|
||||||
|
let msgString: String = msg.withUTF8Buffer { (ptr: UnsafeBufferPointer<UInt8>) -> String in
|
||||||
|
return String(decoding: ptr, as: UTF8.self)
|
||||||
|
}
|
||||||
|
file_log(type: type, message: msgString)
|
||||||
|
}
|
||||||
|
|
||||||
|
func wg_log(_ type: OSLogType, message msg: String) {
|
||||||
|
// Write to os log
|
||||||
|
os_log("%{public}s", log: OSLog.default, type: type, msg)
|
||||||
|
// Write to file log
|
||||||
|
file_log(type: type, message: msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func file_log(type: OSLogType, message: String) {
|
||||||
|
message.withCString { messageCStr in
|
||||||
|
if let logPtr = Logger.logPtr {
|
||||||
|
write_msg_to_log(logPtr, messageCStr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,23 +16,6 @@
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include "ringlogger.h"
|
#include "ringlogger.h"
|
||||||
|
|
||||||
enum {
|
|
||||||
MAX_LOG_LINE_LENGTH = 512,
|
|
||||||
MAX_LINES = 1024,
|
|
||||||
MAGIC = 0xdeadbeefU
|
|
||||||
};
|
|
||||||
|
|
||||||
struct log_line {
|
|
||||||
struct timeval tv;
|
|
||||||
char line[MAX_LOG_LINE_LENGTH];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct log {
|
|
||||||
struct { uint32_t first, len; } header;
|
|
||||||
struct log_line lines[MAX_LINES];
|
|
||||||
uint32_t magic;
|
|
||||||
};
|
|
||||||
|
|
||||||
void write_msg_to_log(struct log *log, const char *msg)
|
void write_msg_to_log(struct log *log, const char *msg)
|
||||||
{
|
{
|
||||||
struct log_line *line = &log->lines[(log->header.first + log->header.len) % MAX_LINES];
|
struct log_line *line = &log->lines[(log->header.first + log->header.len) % MAX_LINES];
|
|
@ -6,7 +6,23 @@
|
||||||
#ifndef RINGLOGGER_H
|
#ifndef RINGLOGGER_H
|
||||||
#define RINGLOGGER_H
|
#define RINGLOGGER_H
|
||||||
|
|
||||||
struct log;
|
enum {
|
||||||
|
MAX_LOG_LINE_LENGTH = 512,
|
||||||
|
MAX_LINES = 1024,
|
||||||
|
MAGIC = 0xdeadbeefU
|
||||||
|
};
|
||||||
|
|
||||||
|
struct log_line {
|
||||||
|
struct timeval tv;
|
||||||
|
char line[MAX_LOG_LINE_LENGTH];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct log {
|
||||||
|
struct { uint32_t first, len; } header;
|
||||||
|
struct log_line lines[MAX_LINES];
|
||||||
|
uint32_t magic;
|
||||||
|
};
|
||||||
|
|
||||||
void write_msg_to_log(struct log *log, const char *msg);
|
void write_msg_to_log(struct log *log, const char *msg);
|
||||||
int write_logs_to_file(const char *file_name, const struct log *log1, const struct log *log2);
|
int write_logs_to_file(const char *file_name, const struct log *log1, const struct log *log2);
|
||||||
struct log *open_log(const char *file_name);
|
struct log *open_log(const char *file_name);
|
|
@ -45,6 +45,10 @@
|
||||||
6FDEF8082187442100D8FBF6 /* WgQuickConfigFileWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FDEF8072187442100D8FBF6 /* WgQuickConfigFileWriter.swift */; };
|
6FDEF8082187442100D8FBF6 /* WgQuickConfigFileWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FDEF8072187442100D8FBF6 /* WgQuickConfigFileWriter.swift */; };
|
||||||
6FE254FB219C10800028284D /* ZipImporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE254FA219C10800028284D /* ZipImporter.swift */; };
|
6FE254FB219C10800028284D /* ZipImporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE254FA219C10800028284D /* ZipImporter.swift */; };
|
||||||
6FE254FF219C60290028284D /* ZipExporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE254FE219C60290028284D /* ZipExporter.swift */; };
|
6FE254FF219C60290028284D /* ZipExporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE254FE219C60290028284D /* ZipExporter.swift */; };
|
||||||
|
6FF3527021C240160008484E /* ringlogger.c in Sources */ = {isa = PBXBuildFile; fileRef = 6FF3526C21C23F960008484E /* ringlogger.c */; };
|
||||||
|
6FF3527121C240160008484E /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FF3526E21C23FA10008484E /* Logger.swift */; };
|
||||||
|
6FF3527221C2616C0008484E /* ringlogger.c in Sources */ = {isa = PBXBuildFile; fileRef = 6FF3526C21C23F960008484E /* ringlogger.c */; };
|
||||||
|
6FF3527321C2616C0008484E /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FF3526E21C23FA10008484E /* Logger.swift */; };
|
||||||
6FF4AC1F211EC472002C96EB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6FF4AC1E211EC472002C96EB /* Assets.xcassets */; };
|
6FF4AC1F211EC472002C96EB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6FF4AC1E211EC472002C96EB /* Assets.xcassets */; };
|
||||||
6FF4AC22211EC472002C96EB /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6FF4AC20211EC472002C96EB /* LaunchScreen.storyboard */; };
|
6FF4AC22211EC472002C96EB /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6FF4AC20211EC472002C96EB /* LaunchScreen.storyboard */; };
|
||||||
6FF717E521B2CB1E0045A474 /* InternetReachability.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FF717E421B2CB1E0045A474 /* InternetReachability.swift */; };
|
6FF717E521B2CB1E0045A474 /* InternetReachability.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FF717E421B2CB1E0045A474 /* InternetReachability.swift */; };
|
||||||
|
@ -139,6 +143,9 @@
|
||||||
6FDEF8072187442100D8FBF6 /* WgQuickConfigFileWriter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WgQuickConfigFileWriter.swift; sourceTree = "<group>"; };
|
6FDEF8072187442100D8FBF6 /* WgQuickConfigFileWriter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WgQuickConfigFileWriter.swift; sourceTree = "<group>"; };
|
||||||
6FE254FA219C10800028284D /* ZipImporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZipImporter.swift; sourceTree = "<group>"; };
|
6FE254FA219C10800028284D /* ZipImporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZipImporter.swift; sourceTree = "<group>"; };
|
||||||
6FE254FE219C60290028284D /* ZipExporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZipExporter.swift; sourceTree = "<group>"; };
|
6FE254FE219C60290028284D /* ZipExporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZipExporter.swift; sourceTree = "<group>"; };
|
||||||
|
6FF3526B21C23F960008484E /* ringlogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ringlogger.h; sourceTree = "<group>"; };
|
||||||
|
6FF3526C21C23F960008484E /* ringlogger.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ringlogger.c; sourceTree = "<group>"; };
|
||||||
|
6FF3526E21C23FA10008484E /* Logger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Logger.swift; sourceTree = "<group>"; };
|
||||||
6FF4AC14211EC46F002C96EB /* WireGuard.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WireGuard.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
6FF4AC14211EC46F002C96EB /* WireGuard.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WireGuard.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
6FF4AC1E211EC472002C96EB /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
6FF4AC1E211EC472002C96EB /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||||
6FF4AC21211EC472002C96EB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
6FF4AC21211EC472002C96EB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||||
|
@ -188,6 +195,7 @@
|
||||||
6F5D0C432183B4A4000F85AD /* Shared */ = {
|
6F5D0C432183B4A4000F85AD /* Shared */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
6FF3526A21C23F720008484E /* Logging */,
|
||||||
6F7774E6217201E0006A79B3 /* Model */,
|
6F7774E6217201E0006A79B3 /* Model */,
|
||||||
6FFA5D942194454A0001E2F7 /* NETunnelProviderProtocol+Extension.swift */,
|
6FFA5D942194454A0001E2F7 /* NETunnelProviderProtocol+Extension.swift */,
|
||||||
6F5A2B4421AFDE020081EDD8 /* FileManager+Extension.swift */,
|
6F5A2B4421AFDE020081EDD8 /* FileManager+Extension.swift */,
|
||||||
|
@ -313,6 +321,16 @@
|
||||||
path = minizip;
|
path = minizip;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
6FF3526A21C23F720008484E /* Logging */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
6FF3526C21C23F960008484E /* ringlogger.c */,
|
||||||
|
6FF3526B21C23F960008484E /* ringlogger.h */,
|
||||||
|
6FF3526E21C23FA10008484E /* Logger.swift */,
|
||||||
|
);
|
||||||
|
path = Logging;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
6FF4AC0B211EC46F002C96EB = {
|
6FF4AC0B211EC46F002C96EB = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -580,6 +598,8 @@
|
||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
6FF3527021C240160008484E /* ringlogger.c in Sources */,
|
||||||
|
6FF3527121C240160008484E /* Logger.swift in Sources */,
|
||||||
6F5A2B4621AFDED40081EDD8 /* FileManager+Extension.swift in Sources */,
|
6F5A2B4621AFDED40081EDD8 /* FileManager+Extension.swift in Sources */,
|
||||||
6FFA5DA021958ECC0001E2F7 /* ErrorNotifier.swift in Sources */,
|
6FFA5DA021958ECC0001E2F7 /* ErrorNotifier.swift in Sources */,
|
||||||
6FFA5D96219446380001E2F7 /* NETunnelProviderProtocol+Extension.swift in Sources */,
|
6FFA5D96219446380001E2F7 /* NETunnelProviderProtocol+Extension.swift in Sources */,
|
||||||
|
@ -597,6 +617,8 @@
|
||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
6FF3527221C2616C0008484E /* ringlogger.c in Sources */,
|
||||||
|
6FF3527321C2616C0008484E /* Logger.swift in Sources */,
|
||||||
6F6899AC218099F00012E523 /* WgQuickConfigFileParser.swift in Sources */,
|
6F6899AC218099F00012E523 /* WgQuickConfigFileParser.swift in Sources */,
|
||||||
6F7774E421718281006A79B3 /* TunnelsListTableViewController.swift in Sources */,
|
6F7774E421718281006A79B3 /* TunnelsListTableViewController.swift in Sources */,
|
||||||
6F7774EF21722D97006A79B3 /* TunnelsManager.swift in Sources */,
|
6F7774EF21722D97006A79B3 /* TunnelsManager.swift in Sources */,
|
||||||
|
|
|
@ -13,6 +13,14 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||||
func application(_ application: UIApplication,
|
func application(_ application: UIApplication,
|
||||||
willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
||||||
|
|
||||||
|
if let appLogFilePath = FileManager.appLogFileURL?.path {
|
||||||
|
if !Logger.configure(withFilePath: appLogFilePath) {
|
||||||
|
os_log("Can't open log file for writing. Log is not saved to file.", log: OSLog.default, type: .error)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
os_log("Can't obtain log file URL. Log is not saved to file.", log: OSLog.default, type: .error)
|
||||||
|
}
|
||||||
|
|
||||||
let window = UIWindow(frame: UIScreen.main.bounds)
|
let window = UIWindow(frame: UIScreen.main.bounds)
|
||||||
window.backgroundColor = UIColor.white
|
window.backgroundColor = UIColor.white
|
||||||
self.window = window
|
self.window = window
|
||||||
|
|
|
@ -108,23 +108,19 @@ class SettingsTableViewController: UITableViewController {
|
||||||
if FileManager.default.fileExists(atPath: destinationURL.path) {
|
if FileManager.default.fileExists(atPath: destinationURL.path) {
|
||||||
let isDeleted = FileManager.deleteFile(at: destinationURL)
|
let isDeleted = FileManager.deleteFile(at: destinationURL)
|
||||||
if !isDeleted {
|
if !isDeleted {
|
||||||
ErrorPresenter.showErrorAlert(title: "No log available", message: "The pre-existing log could not be cleared", from: self)
|
ErrorPresenter.showErrorAlert(title: "Log export failed", message: "The pre-existing log could not be cleared", from: self)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let networkExtensionLogFileURL = FileManager.networkExtensionLogFileURL,
|
guard let networkExtensionLogFilePath = FileManager.networkExtensionLogFileURL?.path else {
|
||||||
FileManager.default.fileExists(atPath: networkExtensionLogFileURL.path) else {
|
ErrorPresenter.showErrorAlert(title: "Log export failed", message: "Internal error obtaining extension log path", from: self)
|
||||||
ErrorPresenter.showErrorAlert(title: "No log available", message: "Please activate a tunnel and then export the log", from: self)
|
return
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
let isWritten = Logger.writeLog(mergedWith: networkExtensionLogFilePath, to: destinationURL.path)
|
||||||
try FileManager.default.copyItem(at: networkExtensionLogFileURL, to: destinationURL)
|
guard isWritten else {
|
||||||
} catch {
|
ErrorPresenter.showErrorAlert(title: "Log export failed", message: "Internal error merging logs", from: self)
|
||||||
os_log("Failed to copy file: %{public}@ to %{public}@: %{public}@", log: OSLog.default, type: .error,
|
|
||||||
networkExtensionLogFileURL.absoluteString, destinationURL.absoluteString, error.localizedDescription)
|
|
||||||
ErrorPresenter.showErrorAlert(title: "Log export failed", message: "The log could not be copied", from: self)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,3 +2,4 @@
|
||||||
#include "unzip.h"
|
#include "unzip.h"
|
||||||
#include "zip.h"
|
#include "zip.h"
|
||||||
#include "wireguard-go-version.h"
|
#include "wireguard-go-version.h"
|
||||||
|
#include "ringlogger.h"
|
||||||
|
|
|
@ -153,15 +153,9 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||||
private func configureLogger() {
|
private func configureLogger() {
|
||||||
|
|
||||||
// Setup writing the log to a file
|
// Setup writing the log to a file
|
||||||
if let networkExtensionLogFileURL = FileManager.networkExtensionLogFileURL {
|
if let networkExtensionLogFilePath = FileManager.networkExtensionLogFileURL?.path {
|
||||||
let fileManager = FileManager.default
|
if !Logger.configure(withFilePath: networkExtensionLogFilePath) {
|
||||||
let filePath = networkExtensionLogFileURL.path
|
|
||||||
fileManager.createFile(atPath: filePath, contents: nil) // Create the file if it doesn't already exist
|
|
||||||
if let fileHandle = FileHandle(forWritingAtPath: filePath) {
|
|
||||||
logFileHandle = fileHandle
|
|
||||||
} else {
|
|
||||||
os_log("Can't open log file for writing. Log is not saved to file.", log: OSLog.default, type: .error)
|
os_log("Can't open log file for writing. Log is not saved to file.", log: OSLog.default, type: .error)
|
||||||
logFileHandle = nil
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
os_log("Can't obtain log file URL. Log is not saved to file.", log: OSLog.default, type: .error)
|
os_log("Can't obtain log file URL. Log is not saved to file.", log: OSLog.default, type: .error)
|
||||||
|
@ -213,34 +207,3 @@ private func withStringsAsGoStrings<R>(_ str1: String, _ str2: String, closure:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func wg_log(_ type: OSLogType, staticMessage msg: StaticString) {
|
|
||||||
// Write to os log
|
|
||||||
os_log(msg, log: OSLog.default, type: type)
|
|
||||||
// Write to file log
|
|
||||||
let msgString: String = msg.withUTF8Buffer { (ptr: UnsafeBufferPointer<UInt8>) -> String in
|
|
||||||
return String(decoding: ptr, as: UTF8.self)
|
|
||||||
}
|
|
||||||
file_log(type: type, message: msgString)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func wg_log(_ type: OSLogType, message msg: String) {
|
|
||||||
// Write to os log
|
|
||||||
os_log("%{public}s", log: OSLog.default, type: type, msg)
|
|
||||||
// Write to file log
|
|
||||||
file_log(type: type, message: msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func file_log(type: OSLogType, message: String) {
|
|
||||||
let formatter = DateFormatter()
|
|
||||||
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss.SSS: "
|
|
||||||
var msgLine = formatter.string(from: Date()) + message
|
|
||||||
if msgLine.last! != "\n" {
|
|
||||||
msgLine.append("\n")
|
|
||||||
}
|
|
||||||
let data = msgLine.data(using: .utf8)
|
|
||||||
if let data = data, let logFileHandle = logFileHandle {
|
|
||||||
logFileHandle.write(data)
|
|
||||||
logFileHandle.synchronizeFile()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
#include "../../wireguard-go-bridge/wireguard.h"
|
#include "../../wireguard-go-bridge/wireguard.h"
|
||||||
#include "wireguard-go-version.h"
|
#include "wireguard-go-version.h"
|
||||||
|
#include "ringlogger.h"
|
||||||
|
|
Loading…
Reference in New Issue