cordova-plugin-unvired-logger 0.0.17 → 0.0.19

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cordova-plugin-unvired-logger",
3
- "version": "0.0.17",
3
+ "version": "0.0.19",
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.17"
2
+ <plugin id="cordova-plugin-unvired-logger" version="0.0.19"
3
3
  xmlns="http://apache.org/cordova/ns/plugins/1.0"
4
4
  xmlns:android="http://schemas.android.com/apk/res/android">
5
5
 
@@ -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());
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cordova-plugin-unvired-logger",
3
- "version": "0.0.17",
3
+ "version": "0.0.19",
4
4
  "description": "Electron platform package for cordova-plugin-unvired-logger",
5
5
  "main": "Logger.js",
6
6
  "scripts": {
@@ -6,6 +6,7 @@ import UIKit
6
6
  private let LOG_FILE_NAME = "log.txt"
7
7
  private let BACKUP_LOG_FILE_NAME = "log_backup.txt"
8
8
  private let MAX_LOG_SIZE: Int64 = 10 * 1024 * 1024 // 10MB
9
+ private let logWriteQueue = DispatchQueue(label: "cordova.plugin.unvired.logger.write")
9
10
 
10
11
  private var defaultLogLevel: Int = 8
11
12
 
@@ -26,8 +27,7 @@ import UIKit
26
27
 
27
28
  @objc(loggerWithLevel:)
28
29
  func loggerWithLevel(_ command: CDVInvokedUrlCommand) {
29
- self.commandDelegate.run(inBackground: {
30
- guard let args = command.arguments.first as? [String: Any] else {
30
+ guard let args = command.arguments.first as? [String: Any] else {
31
31
  self.sendErrorResult(command.callbackId, message: "Invalid arguments")
32
32
  return
33
33
  }
@@ -58,22 +58,32 @@ import UIKit
58
58
 
59
59
  do {
60
60
  let logFile = try self.getLogFile(userId: userId)
61
- try self.checkAndRotateLogFile(logFile: logFile, userId: userId)
62
-
63
61
  let logEntry = self.formatLogEntry(level: level, sourceClass: sourceClass, sourceMethod: sourceMethod, message: message)
64
62
 
65
- // Perform file write in background
66
- self.appendToFile(file: logFile, data: logEntry) { error in
67
- if let error = error {
68
- self.sendErrorResult(command.callbackId, message: "Logging failed: \(error.localizedDescription)")
69
- } else {
70
- self.sendSuccessResult(command.callbackId, message: "Logged to \(logFile.path)")
63
+ // Print to console before writing to file
64
+ NSLog("%@", logEntry.trimmingCharacters(in: .whitespacesAndNewlines))
65
+ self.commandDelegate.run(inBackground: {
66
+ // Serialize rotation + write to guarantee ordering
67
+ self.logWriteQueue.async {
68
+ do {
69
+ try self.checkAndRotateLogFile(logFile: logFile, userId: userId)
70
+ self.appendToFile(file: logFile, data: logEntry) { error in
71
+ if let error = error {
72
+ self.sendErrorResult(command.callbackId, message: "Logging failed: \(error.localizedDescription)")
73
+ } else {
74
+ self.sendSuccessResult(command.callbackId, message: "Logged to \(logFile.path)")
75
+ }
76
+ }
77
+ } catch {
78
+ self.sendErrorResult(command.callbackId, message: "Logging failed: \(error.localizedDescription)")
79
+ }
71
80
  }
72
- }
81
+ })
73
82
  } catch {
74
- self.sendErrorResult(command.callbackId, message: "Logging failed: \(error.localizedDescription)")
83
+ self.commandDelegate.run(inBackground: {
84
+ self.sendErrorResult(command.callbackId, message: "Logging failed: \(error.localizedDescription)")
85
+ })
75
86
  }
76
- })
77
87
  }
78
88
 
79
89
  @objc(setLogLevel:)
@@ -227,7 +237,9 @@ import UIKit
227
237
  let userDir = documentsPath.appendingPathComponent(userId)
228
238
 
229
239
  if !FileManager.default.fileExists(atPath: userDir.path) {
230
- try FileManager.default.createDirectory(at: userDir, withIntermediateDirectories: true, attributes: nil)
240
+ try FileManager.default.createDirectory(at: userDir, withIntermediateDirectories: true, attributes: [
241
+ .protectionKey: FileProtectionType.none
242
+ ])
231
243
  }
232
244
 
233
245
  return userDir
@@ -271,16 +283,38 @@ import UIKit
271
283
  private func appendToFile(file: URL, data: String, completion: @escaping (Error?) -> Void = { _ in }) {
272
284
  do {
273
285
  let fileManager = FileManager.default
286
+ // Ensure parent directory exists (defensive)
287
+ let parentDirectory = file.deletingLastPathComponent()
288
+ if !fileManager.fileExists(atPath: parentDirectory.path) {
289
+ try fileManager.createDirectory(at: parentDirectory, withIntermediateDirectories: true, attributes: [
290
+ .protectionKey: FileProtectionType.none
291
+ ])
292
+ }
293
+ // Create the file if it doesn't exist with safe attributes
274
294
  if !fileManager.fileExists(atPath: file.path) {
275
- // Create the file if it doesn't exist
276
- fileManager.createFile(atPath: file.path, contents: nil, attributes: nil)
295
+ fileManager.createFile(atPath: file.path, contents: nil, attributes: [
296
+ .protectionKey: FileProtectionType.none
297
+ ])
277
298
  }
299
+ let utf8Data = data.data(using: .utf8) ?? Data()
278
300
  let fileHandle = try FileHandle(forWritingTo: file)
279
- fileHandle.seekToEndOfFile()
280
- fileHandle.write(data.data(using: .utf8)!)
281
- fileHandle.closeFile()
301
+ defer {
302
+ if #available(iOS 13.0, *) {
303
+ try? fileHandle.close()
304
+ } else {
305
+ fileHandle.closeFile()
306
+ }
307
+ }
308
+ if #available(iOS 13.4, *) {
309
+ try fileHandle.seekToEnd()
310
+ try fileHandle.write(contentsOf: utf8Data)
311
+ } else {
312
+ fileHandle.seekToEndOfFile()
313
+ fileHandle.write(utf8Data)
314
+ }
282
315
  completion(nil)
283
316
  } catch {
317
+ NSLog("[Logger] Failed to append to file: \(error.localizedDescription)")
284
318
  completion(error)
285
319
  }
286
320
  }
@@ -293,10 +327,14 @@ import UIKit
293
327
  }
294
328
 
295
329
  private func copyFile(from: URL, to: URL) throws {
296
- if !FileManager.default.fileExists(atPath: from.path) {
330
+ let fileManager = FileManager.default
331
+ if !fileManager.fileExists(atPath: from.path) {
297
332
  return
298
333
  }
299
- try FileManager.default.copyItem(at: from, to: to)
334
+ if fileManager.fileExists(atPath: to.path) {
335
+ try fileManager.removeItem(at: to)
336
+ }
337
+ try fileManager.copyItem(at: from, to: to)
300
338
  }
301
339
 
302
340
  private func sendSuccessResult(_ callbackId: String, message: String) {