cordova-plugin-unvired-logger 0.0.16 → 0.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/plugin.xml +1 -1
- package/src/android/Logger.java +4 -0
- package/src/electron/package.json +1 -1
- package/src/ios/Logger.swift +155 -145
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cordova-plugin-unvired-logger",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.18",
|
|
4
4
|
"description": "A logger plugin for Electron, Android, Browser, and iOS that appends logs to log.txt files organized by user ID.",
|
|
5
5
|
"cordova": {
|
|
6
6
|
"id": "cordova-plugin-unvired-logger",
|
package/plugin.xml
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<plugin id="cordova-plugin-unvired-logger" version="0.0.
|
|
2
|
+
<plugin id="cordova-plugin-unvired-logger" version="0.0.18"
|
|
3
3
|
xmlns="http://apache.org/cordova/ns/plugins/1.0"
|
|
4
4
|
xmlns:android="http://schemas.android.com/apk/res/android">
|
|
5
5
|
|
package/src/android/Logger.java
CHANGED
|
@@ -132,6 +132,10 @@ public class Logger extends CordovaPlugin {
|
|
|
132
132
|
checkAndRotateLogFile(logFile, userId);
|
|
133
133
|
|
|
134
134
|
String logEntry = formatLogEntry(level, sourceClass, sourceMethod, message);
|
|
135
|
+
|
|
136
|
+
// Print to console before writing to file
|
|
137
|
+
System.out.println(logEntry.trim());
|
|
138
|
+
|
|
135
139
|
appendToFile(logFile, logEntry);
|
|
136
140
|
|
|
137
141
|
callbackContext.success("Logged to " + logFile.getAbsolutePath());
|
package/src/ios/Logger.swift
CHANGED
|
@@ -8,7 +8,6 @@ import UIKit
|
|
|
8
8
|
private let MAX_LOG_SIZE: Int64 = 10 * 1024 * 1024 // 10MB
|
|
9
9
|
|
|
10
10
|
private var defaultLogLevel: Int = 8
|
|
11
|
-
private let fileWriteQueue = DispatchQueue(label: "com.logger.filewrite", qos: .background)
|
|
12
11
|
|
|
13
12
|
@objc(logDebug:)
|
|
14
13
|
func logDebug(_ command: CDVInvokedUrlCommand) {
|
|
@@ -27,53 +26,57 @@ import UIKit
|
|
|
27
26
|
|
|
28
27
|
@objc(loggerWithLevel:)
|
|
29
28
|
func loggerWithLevel(_ command: CDVInvokedUrlCommand) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
guard let message = args["message"] as? String, !message.isEmpty else {
|
|
46
|
-
sendErrorResult(command.callbackId, message: "message is required")
|
|
47
|
-
return
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
let sourceClass = args["sourceClass"] as? String ?? ""
|
|
51
|
-
let sourceMethod = args["sourceMethod"] as? String ?? ""
|
|
52
|
-
|
|
53
|
-
// Log level filtering
|
|
54
|
-
if shouldSkipLog(level: level) {
|
|
55
|
-
sendSuccessResult(command.callbackId, message: "Log skipped due to level filter")
|
|
56
|
-
return
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
do {
|
|
60
|
-
let logFile = try getLogFile(userId: userId)
|
|
61
|
-
try checkAndRotateLogFile(logFile: logFile, userId: userId)
|
|
29
|
+
self.commandDelegate.run(inBackground: {
|
|
30
|
+
guard let args = command.arguments.first as? [String: Any] else {
|
|
31
|
+
self.sendErrorResult(command.callbackId, message: "Invalid arguments")
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
guard let userId = args["userId"] as? String, !userId.isEmpty else {
|
|
36
|
+
self.sendErrorResult(command.callbackId, message: "userId is required")
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
guard let level = args["level"] as? Int else {
|
|
41
|
+
self.sendErrorResult(command.callbackId, message: "level is required")
|
|
42
|
+
return
|
|
43
|
+
}
|
|
62
44
|
|
|
63
|
-
let
|
|
45
|
+
guard let message = args["message"] as? String, !message.isEmpty else {
|
|
46
|
+
self.sendErrorResult(command.callbackId, message: "message is required")
|
|
47
|
+
return
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let sourceClass = args["sourceClass"] as? String ?? ""
|
|
51
|
+
let sourceMethod = args["sourceMethod"] as? String ?? ""
|
|
64
52
|
|
|
65
|
-
//
|
|
66
|
-
|
|
53
|
+
// Log level filtering
|
|
54
|
+
if self.shouldSkipLog(level: level) {
|
|
55
|
+
self.sendSuccessResult(command.callbackId, message: "Log skipped due to level filter")
|
|
56
|
+
return
|
|
57
|
+
}
|
|
67
58
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
59
|
+
do {
|
|
60
|
+
let logFile = try self.getLogFile(userId: userId)
|
|
61
|
+
try self.checkAndRotateLogFile(logFile: logFile, userId: userId)
|
|
62
|
+
|
|
63
|
+
let logEntry = self.formatLogEntry(level: level, sourceClass: sourceClass, sourceMethod: sourceMethod, message: message)
|
|
64
|
+
|
|
65
|
+
// Print to console before writing to file
|
|
66
|
+
print(logEntry.trimmingCharacters(in: .whitespacesAndNewlines))
|
|
67
|
+
|
|
68
|
+
// Perform file write in background
|
|
69
|
+
self.appendToFile(file: logFile, data: logEntry) { error in
|
|
70
|
+
if let error = error {
|
|
71
|
+
self.sendErrorResult(command.callbackId, message: "Logging failed: \(error.localizedDescription)")
|
|
72
|
+
} else {
|
|
73
|
+
self.sendSuccessResult(command.callbackId, message: "Logged to \(logFile.path)")
|
|
74
|
+
}
|
|
72
75
|
}
|
|
76
|
+
} catch {
|
|
77
|
+
self.sendErrorResult(command.callbackId, message: "Logging failed: \(error.localizedDescription)")
|
|
73
78
|
}
|
|
74
|
-
}
|
|
75
|
-
sendErrorResult(command.callbackId, message: "Logging failed: \(error.localizedDescription)")
|
|
76
|
-
}
|
|
79
|
+
})
|
|
77
80
|
}
|
|
78
81
|
|
|
79
82
|
@objc(setLogLevel:)
|
|
@@ -95,103 +98,115 @@ import UIKit
|
|
|
95
98
|
|
|
96
99
|
@objc(getLogFileContent:)
|
|
97
100
|
func getLogFileContent(_ command: CDVInvokedUrlCommand) {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
101
|
+
self.commandDelegate.run(inBackground: {
|
|
102
|
+
guard let args = command.arguments.first as? [String: Any],
|
|
103
|
+
let userId = args["userId"] as? String else {
|
|
104
|
+
self.sendErrorResult(command.callbackId, message: "userId is required")
|
|
105
|
+
return
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
do {
|
|
109
|
+
let logFile = try self.getLogFile(userId: userId)
|
|
110
|
+
let content = try self.readFile(file: logFile)
|
|
111
|
+
self.sendSuccessResult(command.callbackId, message: content)
|
|
112
|
+
} catch {
|
|
113
|
+
self.sendErrorResult(command.callbackId, message: "Failed to read log file: \(error.localizedDescription)")
|
|
114
|
+
}
|
|
115
|
+
})
|
|
111
116
|
}
|
|
112
117
|
|
|
113
118
|
@objc(clearLogFile:)
|
|
114
119
|
func clearLogFile(_ command: CDVInvokedUrlCommand) {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
120
|
+
self.commandDelegate.run(inBackground: {
|
|
121
|
+
guard let args = command.arguments.first as? [String: Any],
|
|
122
|
+
let userId = args["userId"] as? String else {
|
|
123
|
+
self.sendErrorResult(command.callbackId, message: "userId is required")
|
|
124
|
+
return
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
do {
|
|
128
|
+
let logFile = try self.getLogFile(userId: userId)
|
|
129
|
+
try "".write(to: logFile, atomically: true, encoding: .utf8)
|
|
130
|
+
self.sendSuccessResult(command.callbackId, message: "Log file cleared")
|
|
131
|
+
} catch {
|
|
132
|
+
self.sendErrorResult(command.callbackId, message: "Failed to clear log file: \(error.localizedDescription)")
|
|
133
|
+
}
|
|
134
|
+
})
|
|
128
135
|
}
|
|
129
136
|
|
|
130
137
|
@objc(getBackupLogFileContent:)
|
|
131
138
|
func getBackupLogFileContent(_ command: CDVInvokedUrlCommand) {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
139
|
+
self.commandDelegate.run(inBackground: {
|
|
140
|
+
guard let args = command.arguments.first as? [String: Any],
|
|
141
|
+
let userId = args["userId"] as? String else {
|
|
142
|
+
self.sendErrorResult(command.callbackId, message: "userId is required")
|
|
143
|
+
return
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
do {
|
|
147
|
+
let backupFile = try self.getBackupLogFile(userId: userId)
|
|
148
|
+
let content = try self.readFile(file: backupFile)
|
|
149
|
+
self.sendSuccessResult(command.callbackId, message: content)
|
|
150
|
+
} catch {
|
|
151
|
+
self.sendErrorResult(command.callbackId, message: "Failed to read backup log file: \(error.localizedDescription)")
|
|
152
|
+
}
|
|
153
|
+
})
|
|
145
154
|
}
|
|
146
155
|
|
|
147
156
|
@objc(copyLogToBackup:)
|
|
148
157
|
func copyLogToBackup(_ command: CDVInvokedUrlCommand) {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
158
|
+
self.commandDelegate.run(inBackground: {
|
|
159
|
+
guard let args = command.arguments.first as? [String: Any],
|
|
160
|
+
let userId = args["userId"] as? String else {
|
|
161
|
+
self.sendErrorResult(command.callbackId, message: "userId is required")
|
|
162
|
+
return
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
do {
|
|
166
|
+
let logFile = try self.getLogFile(userId: userId)
|
|
167
|
+
let backupFile = try self.getBackupLogFile(userId: userId)
|
|
168
|
+
try self.copyFile(from: logFile, to: backupFile)
|
|
169
|
+
self.sendSuccessResult(command.callbackId, message: "Log file copied to backup")
|
|
170
|
+
} catch {
|
|
171
|
+
self.sendErrorResult(command.callbackId, message: "Failed to copy log file to backup: \(error.localizedDescription)")
|
|
172
|
+
}
|
|
173
|
+
})
|
|
163
174
|
}
|
|
164
175
|
|
|
165
176
|
@objc(getLogFileURL:)
|
|
166
177
|
func getLogFileURL(_ command: CDVInvokedUrlCommand) {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
178
|
+
self.commandDelegate.run(inBackground: {
|
|
179
|
+
guard let args = command.arguments.first as? [String: Any],
|
|
180
|
+
let userId = args["userId"] as? String else {
|
|
181
|
+
self.sendErrorResult(command.callbackId, message: "userId is required")
|
|
182
|
+
return
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
do {
|
|
186
|
+
let logFile = try self.getLogFile(userId: userId)
|
|
187
|
+
self.sendSuccessResult(command.callbackId, message: logFile.path)
|
|
188
|
+
} catch {
|
|
189
|
+
self.sendErrorResult(command.callbackId, message: "Failed to get log file URL: \(error.localizedDescription)")
|
|
190
|
+
}
|
|
191
|
+
})
|
|
179
192
|
}
|
|
180
193
|
|
|
181
194
|
@objc(getBackupLogFileURL:)
|
|
182
195
|
func getBackupLogFileURL(_ command: CDVInvokedUrlCommand) {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
196
|
+
self.commandDelegate.run(inBackground: {
|
|
197
|
+
guard let args = command.arguments.first as? [String: Any],
|
|
198
|
+
let userId = args["userId"] as? String else {
|
|
199
|
+
self.sendErrorResult(command.callbackId, message: "userId is required")
|
|
200
|
+
return
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
do {
|
|
204
|
+
let backupFile = try self.getBackupLogFile(userId: userId)
|
|
205
|
+
self.sendSuccessResult(command.callbackId, message: backupFile.path)
|
|
206
|
+
} catch {
|
|
207
|
+
self.sendErrorResult(command.callbackId, message: "Failed to get backup log file URL: \(error.localizedDescription)")
|
|
208
|
+
}
|
|
209
|
+
})
|
|
195
210
|
}
|
|
196
211
|
|
|
197
212
|
// MARK: - Helper Methods
|
|
@@ -257,28 +272,19 @@ import UIKit
|
|
|
257
272
|
}
|
|
258
273
|
|
|
259
274
|
private func appendToFile(file: URL, data: String, completion: @escaping (Error?) -> Void = { _ in }) {
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
fileManager.createFile(atPath: file.path, contents: nil, attributes: nil)
|
|
266
|
-
}
|
|
267
|
-
let fileHandle = try FileHandle(forWritingTo: file)
|
|
268
|
-
fileHandle.seekToEndOfFile()
|
|
269
|
-
fileHandle.write(data.data(using: .utf8)!)
|
|
270
|
-
fileHandle.closeFile()
|
|
271
|
-
|
|
272
|
-
// Notify success on main thread
|
|
273
|
-
DispatchQueue.main.async {
|
|
274
|
-
completion(nil)
|
|
275
|
-
}
|
|
276
|
-
} catch {
|
|
277
|
-
// Notify error on main thread
|
|
278
|
-
DispatchQueue.main.async {
|
|
279
|
-
completion(error)
|
|
280
|
-
}
|
|
275
|
+
do {
|
|
276
|
+
let fileManager = FileManager.default
|
|
277
|
+
if !fileManager.fileExists(atPath: file.path) {
|
|
278
|
+
// Create the file if it doesn't exist
|
|
279
|
+
fileManager.createFile(atPath: file.path, contents: nil, attributes: nil)
|
|
281
280
|
}
|
|
281
|
+
let fileHandle = try FileHandle(forWritingTo: file)
|
|
282
|
+
fileHandle.seekToEndOfFile()
|
|
283
|
+
fileHandle.write(data.data(using: .utf8)!)
|
|
284
|
+
fileHandle.closeFile()
|
|
285
|
+
completion(nil)
|
|
286
|
+
} catch {
|
|
287
|
+
completion(error)
|
|
282
288
|
}
|
|
283
289
|
}
|
|
284
290
|
|
|
@@ -297,12 +303,16 @@ import UIKit
|
|
|
297
303
|
}
|
|
298
304
|
|
|
299
305
|
private func sendSuccessResult(_ callbackId: String, message: String) {
|
|
300
|
-
|
|
301
|
-
|
|
306
|
+
DispatchQueue.main.async {
|
|
307
|
+
let result = CDVPluginResult(status: CDVCommandStatus_OK, messageAs: message)
|
|
308
|
+
self.commandDelegate.send(result, callbackId: callbackId)
|
|
309
|
+
}
|
|
302
310
|
}
|
|
303
311
|
|
|
304
312
|
private func sendErrorResult(_ callbackId: String, message: String) {
|
|
305
|
-
|
|
306
|
-
|
|
313
|
+
DispatchQueue.main.async {
|
|
314
|
+
let result = CDVPluginResult(status: CDVCommandStatus_ERROR, messageAs: message)
|
|
315
|
+
self.commandDelegate.send(result, callbackId: callbackId)
|
|
316
|
+
}
|
|
307
317
|
}
|
|
308
318
|
}
|