cordova-plugin-unvired-logger 0.0.13 → 0.0.15
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 +53 -23
- package/src/browser/Logger.js +27 -33
- package/src/electron/Logger.js +29 -33
- package/src/electron/package.json +1 -1
- package/src/ios/Logger.swift +51 -38
- package/www/logger.js +14 -4
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.15",
|
|
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.15"
|
|
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
|
@@ -14,13 +14,20 @@ import java.text.SimpleDateFormat;
|
|
|
14
14
|
import java.util.Date;
|
|
15
15
|
import java.util.Locale;
|
|
16
16
|
|
|
17
|
+
|
|
17
18
|
public class Logger extends CordovaPlugin {
|
|
18
19
|
|
|
19
20
|
private static final String LOG_FILE_NAME = "log.txt";
|
|
20
21
|
private static final String BACKUP_LOG_FILE_NAME = "log_backup.txt";
|
|
21
|
-
private static final long MAX_LOG_SIZE =
|
|
22
|
+
private static final long MAX_LOG_SIZE = 10 * 1024 * 1024; // 10MB
|
|
23
|
+
|
|
24
|
+
// LogLevel constants as int
|
|
25
|
+
private static final int LOG_LEVEL_DEBUG = 7;
|
|
26
|
+
private static final int LOG_LEVEL_ERROR = 8;
|
|
27
|
+
private static final int LOG_LEVEL_INFO = 9;
|
|
28
|
+
|
|
29
|
+
private int defaultLogLevel = LOG_LEVEL_INFO;
|
|
22
30
|
|
|
23
|
-
private String defaultLogLevel = "important";
|
|
24
31
|
|
|
25
32
|
@Override
|
|
26
33
|
public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException {
|
|
@@ -36,7 +43,7 @@ public class Logger extends CordovaPlugin {
|
|
|
36
43
|
setLogLevel(args, callbackContext);
|
|
37
44
|
return true;
|
|
38
45
|
case "getLogLevel":
|
|
39
|
-
callbackContext.success(defaultLogLevel);
|
|
46
|
+
callbackContext.success(Integer.toString(defaultLogLevel));
|
|
40
47
|
return true;
|
|
41
48
|
case "getLogFileContent":
|
|
42
49
|
getLogFileContent(args, callbackContext);
|
|
@@ -67,8 +74,21 @@ public class Logger extends CordovaPlugin {
|
|
|
67
74
|
|
|
68
75
|
private void setLogLevel(JSONArray args, CallbackContext callbackContext) {
|
|
69
76
|
try {
|
|
70
|
-
|
|
71
|
-
|
|
77
|
+
Object levelObj = args.get(0);
|
|
78
|
+
int levelInt = LOG_LEVEL_INFO;
|
|
79
|
+
if (levelObj instanceof Integer) {
|
|
80
|
+
levelInt = (Integer) levelObj;
|
|
81
|
+
} else if (levelObj instanceof String) {
|
|
82
|
+
try {
|
|
83
|
+
levelInt = Integer.parseInt((String) levelObj);
|
|
84
|
+
} catch (NumberFormatException e) {
|
|
85
|
+
String levelStr = ((String) levelObj).toLowerCase();
|
|
86
|
+
if (levelStr.equals("debug")) levelInt = LOG_LEVEL_DEBUG;
|
|
87
|
+
else if (levelStr.equals("error")) levelInt = LOG_LEVEL_ERROR;
|
|
88
|
+
else if (levelStr.equals("important")) levelInt = LOG_LEVEL_INFO;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
defaultLogLevel = levelInt;
|
|
72
92
|
callbackContext.success();
|
|
73
93
|
} catch (Exception e) {
|
|
74
94
|
callbackContext.error("Failed to set log level: " + e.getMessage());
|
|
@@ -79,13 +99,26 @@ public class Logger extends CordovaPlugin {
|
|
|
79
99
|
try {
|
|
80
100
|
JSONObject arg = args.getJSONObject(0);
|
|
81
101
|
String userId = arg.optString("userId");
|
|
82
|
-
|
|
102
|
+
Object levelObj = arg.opt("level");
|
|
103
|
+
int level = LOG_LEVEL_INFO;
|
|
104
|
+
if (levelObj instanceof Integer) {
|
|
105
|
+
level = (Integer) levelObj;
|
|
106
|
+
} else if (levelObj instanceof String) {
|
|
107
|
+
try {
|
|
108
|
+
level = Integer.parseInt((String) levelObj);
|
|
109
|
+
} catch (NumberFormatException e) {
|
|
110
|
+
String levelStr = ((String) levelObj).toLowerCase();
|
|
111
|
+
if (levelStr.equals("debug")) level = LOG_LEVEL_DEBUG;
|
|
112
|
+
else if (levelStr.equals("error")) level = LOG_LEVEL_ERROR;
|
|
113
|
+
else if (levelStr.equals("important")) level = LOG_LEVEL_INFO;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
83
116
|
String sourceClass = arg.optString("sourceClass", "");
|
|
84
117
|
String sourceMethod = arg.optString("sourceMethod", "");
|
|
85
118
|
String message = arg.optString("message");
|
|
86
119
|
|
|
87
|
-
if (userId.isEmpty() ||
|
|
88
|
-
callbackContext.error("userId
|
|
120
|
+
if (userId.isEmpty() || message.isEmpty()) {
|
|
121
|
+
callbackContext.error("userId and message are required");
|
|
89
122
|
return;
|
|
90
123
|
}
|
|
91
124
|
|
|
@@ -107,12 +140,8 @@ public class Logger extends CordovaPlugin {
|
|
|
107
140
|
}
|
|
108
141
|
}
|
|
109
142
|
|
|
110
|
-
private boolean shouldSkipLog(
|
|
111
|
-
|
|
112
|
-
String normDefault = defaultLogLevel.toLowerCase();
|
|
113
|
-
if (normDefault.equals("error") && (normLevel.equals("debug") || normLevel.equals("important"))) return true;
|
|
114
|
-
if (normDefault.equals("important") && normLevel.equals("debug")) return true;
|
|
115
|
-
return false;
|
|
143
|
+
private boolean shouldSkipLog(int level) {
|
|
144
|
+
return level > defaultLogLevel;
|
|
116
145
|
}
|
|
117
146
|
|
|
118
147
|
private void getLogFileContent(JSONArray args, CallbackContext callbackContext) {
|
|
@@ -215,22 +244,23 @@ public class Logger extends CordovaPlugin {
|
|
|
215
244
|
}
|
|
216
245
|
}
|
|
217
246
|
|
|
218
|
-
private String formatLogEntry(
|
|
219
|
-
|
|
220
|
-
SimpleDateFormat
|
|
247
|
+
private String formatLogEntry(int level, String sourceClass, String sourceMethod, String message) {
|
|
248
|
+
// Include milliseconds in the format
|
|
249
|
+
SimpleDateFormat localFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss.SSS", Locale.getDefault());
|
|
250
|
+
SimpleDateFormat utcFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss.SSS", Locale.US);
|
|
221
251
|
utcFormat.setTimeZone(java.util.TimeZone.getTimeZone("UTC"));
|
|
222
252
|
Date now = new Date();
|
|
223
253
|
String local = localFormat.format(now);
|
|
224
254
|
String utc = utcFormat.format(now);
|
|
225
|
-
String prefix = level
|
|
255
|
+
String prefix = (level == LOG_LEVEL_ERROR) ? "⭕️⭕️⭕️ " : "";
|
|
226
256
|
return prefix + local + " | UTC:" + utc + " | " + getStringFromLevel(level) + " | " + sourceClass + " | " + sourceMethod + " | " + message + "\n";
|
|
227
257
|
}
|
|
228
258
|
|
|
229
|
-
private String getStringFromLevel(
|
|
230
|
-
switch (level
|
|
231
|
-
case
|
|
232
|
-
case
|
|
233
|
-
case
|
|
259
|
+
private String getStringFromLevel(int level) {
|
|
260
|
+
switch (level) {
|
|
261
|
+
case LOG_LEVEL_INFO: return "IMPORTANT";
|
|
262
|
+
case LOG_LEVEL_ERROR: return "ERROR";
|
|
263
|
+
case LOG_LEVEL_DEBUG: return "DEBUG";
|
|
234
264
|
default: return "";
|
|
235
265
|
}
|
|
236
266
|
}
|
package/src/browser/Logger.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
const LOG_FILE_NAME = 'log.txt';
|
|
2
2
|
const BACKUP_LOG_FILE_NAME = 'log_backup.txt';
|
|
3
|
-
const MAX_LOG_SIZE =
|
|
3
|
+
const MAX_LOG_SIZE = 10 * 1024 * 1024; // 10MB
|
|
4
4
|
|
|
5
5
|
const LogLevel = {
|
|
6
|
-
Debug:
|
|
7
|
-
Error:
|
|
8
|
-
Info:
|
|
6
|
+
Debug: 7,
|
|
7
|
+
Error: 8,
|
|
8
|
+
Info: 9,
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
-
let defaultLogLevel = LogLevel.Info;
|
|
11
|
+
let defaultLogLevel = LogLevel.Info; // Now an int
|
|
12
12
|
|
|
13
13
|
// Browser storage keys
|
|
14
14
|
const getStorageKey = (userId, fileName) => `unvired_logger_${userId}_${fileName}`;
|
|
@@ -29,15 +29,18 @@ module.exports.logInfo = async function (successCallback, errorCallback, args) {
|
|
|
29
29
|
module.exports.setLogLevel = function(successCallback, errorCallback, level) {
|
|
30
30
|
// If level is an array (from Cordova), extract the first element
|
|
31
31
|
let levelToSet = Array.isArray(level) ? level[0] : level;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
// Convert to int if string
|
|
33
|
+
if (typeof levelToSet === 'string') {
|
|
34
|
+
levelToSet = parseInt(levelToSet, 10);
|
|
35
|
+
}
|
|
36
|
+
if (Number.isInteger(levelToSet)) {
|
|
37
|
+
defaultLogLevel = levelToSet;
|
|
38
|
+
}
|
|
36
39
|
successCallback("");
|
|
37
40
|
}
|
|
38
41
|
|
|
39
42
|
module.exports.getLogLevel = function(successCallback, errorCallback) {
|
|
40
|
-
successCallback(defaultLogLevel)
|
|
43
|
+
successCallback(defaultLogLevel + "")
|
|
41
44
|
}
|
|
42
45
|
|
|
43
46
|
module.exports.getLogFileURL = function(successCallback, errorCallback, args) {
|
|
@@ -114,39 +117,30 @@ async function logWitLevel(successCallback, errorCallback, args) {
|
|
|
114
117
|
return errorCallback(new Error("Invalid arguments provided"));
|
|
115
118
|
}
|
|
116
119
|
|
|
117
|
-
|
|
120
|
+
let { userId, level, sourceClass, sourceMethod, message } = args[0];
|
|
118
121
|
|
|
119
122
|
if (!userId) return errorCallback(new Error("userId is required"));
|
|
120
|
-
if (
|
|
123
|
+
if (level === undefined || level === null) return errorCallback(new Error("level is required"));
|
|
121
124
|
if (!message) return errorCallback(new Error("message is required"));
|
|
122
125
|
|
|
123
|
-
//
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
if (
|
|
129
|
-
(normalizedDefaultLogLevel === LogLevel.Error && (normalizedLevel === LogLevel.Debug || normalizedLevel === LogLevel.Info)) ||
|
|
130
|
-
(normalizedDefaultLogLevel === LogLevel.Info && normalizedLevel === LogLevel.Debug)
|
|
131
|
-
) {
|
|
126
|
+
// Convert level to int if string
|
|
127
|
+
if (typeof level === 'string') {
|
|
128
|
+
level = parseInt(level, 8);
|
|
129
|
+
}
|
|
130
|
+
if (level > defaultLogLevel) {
|
|
132
131
|
return successCallback();
|
|
133
132
|
}
|
|
134
133
|
|
|
135
134
|
await checkAndRotateLogFile(args);
|
|
136
135
|
|
|
137
136
|
const currentDate = new Date();
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
const utcFormatter = new Intl.DateTimeFormat('en-US', {
|
|
146
|
-
day: '2-digit', month: '2-digit', year: 'numeric',
|
|
147
|
-
hour: '2-digit', minute: '2-digit', second: '2-digit', timeZone: 'UTC'
|
|
148
|
-
});
|
|
149
|
-
const utcDateString = utcFormatter.format(dateUtc);
|
|
137
|
+
// Format with milliseconds manually
|
|
138
|
+
function pad(n, z = 2) { return ('00' + n).slice(-z); }
|
|
139
|
+
const localDateString = `${pad(currentDate.getDate())}-${pad(currentDate.getMonth() + 1)}-${currentDate.getFullYear()} ` +
|
|
140
|
+
`${pad(currentDate.getHours())}:${pad(currentDate.getMinutes())}:${pad(currentDate.getSeconds())}.${pad(currentDate.getMilliseconds(), 3)}`;
|
|
141
|
+
|
|
142
|
+
const utcDateString = `${pad(currentDate.getUTCDate())}-${pad(currentDate.getUTCMonth() + 1)}-${currentDate.getUTCFullYear()} ` +
|
|
143
|
+
`${pad(currentDate.getUTCHours())}:${pad(currentDate.getUTCMinutes())}:${pad(currentDate.getUTCSeconds())}.${pad(currentDate.getUTCMilliseconds(), 3)}`;
|
|
150
144
|
|
|
151
145
|
let data = `${localDateString} | UTC:${utcDateString} | ${getStringFromLevel(level)} | ${sourceClass} | ${sourceMethod} | ${message}\n`;
|
|
152
146
|
if (level === LogLevel.Error) {
|
package/src/electron/Logger.js
CHANGED
|
@@ -36,13 +36,13 @@ const LOG_FILE_NAME = 'log.txt';
|
|
|
36
36
|
const BACKUP_LOG_FILE_NAME = 'log_backup.txt';
|
|
37
37
|
|
|
38
38
|
const LogLevel = {
|
|
39
|
-
Debug:
|
|
40
|
-
Error:
|
|
41
|
-
Info:
|
|
39
|
+
Debug: 9,
|
|
40
|
+
Error: 8,
|
|
41
|
+
Info: 7,
|
|
42
42
|
};
|
|
43
43
|
|
|
44
|
-
let defaultLogLevel = LogLevel.Info;
|
|
45
|
-
const MAX_LOG_SIZE =
|
|
44
|
+
let defaultLogLevel = LogLevel.Info; // Now an int
|
|
45
|
+
const MAX_LOG_SIZE = 10 * 1024 * 1024; // 10MB
|
|
46
46
|
|
|
47
47
|
function logDebug(args) {
|
|
48
48
|
return loggerWithLevel(args);
|
|
@@ -59,14 +59,18 @@ function logInfo(args) {
|
|
|
59
59
|
function setLogLevel(level) {
|
|
60
60
|
// If level is an array (from Cordova), extract the first element
|
|
61
61
|
let levelToSet = Array.isArray(level) ? level[0] : level;
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
// Convert to int if string
|
|
63
|
+
if (typeof levelToSet === 'string') {
|
|
64
|
+
levelToSet = parseInt(levelToSet, 8);
|
|
65
|
+
}
|
|
66
|
+
if (Number.isInteger(levelToSet)) {
|
|
67
|
+
defaultLogLevel = levelToSet;
|
|
68
|
+
}
|
|
65
69
|
}
|
|
66
70
|
|
|
67
71
|
function getLogLevel() {
|
|
68
72
|
return new Promise((resolve) => {
|
|
69
|
-
resolve(defaultLogLevel);
|
|
73
|
+
resolve(defaultLogLevel + "");
|
|
70
74
|
});
|
|
71
75
|
}
|
|
72
76
|
|
|
@@ -132,39 +136,31 @@ function copyLogToBackup(args) {
|
|
|
132
136
|
function loggerWithLevel(args) {
|
|
133
137
|
return withLogLock(async () => {
|
|
134
138
|
if (!args || !args[0]) throw new Error("Invalid arguments provided");
|
|
135
|
-
|
|
139
|
+
let { userId, level, sourceClass, sourceMethod, message } = args[0];
|
|
136
140
|
if (!userId) throw new Error("userId is required");
|
|
137
|
-
if (
|
|
141
|
+
if (level === undefined || level === null) throw new Error("level is required");
|
|
138
142
|
if (!message) throw new Error("message is required");
|
|
139
143
|
|
|
140
|
-
//
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
// Log level filtering using normalized values
|
|
145
|
-
if (
|
|
146
|
-
(normalizedDefaultLogLevel === LogLevel.Error && (normalizedLevel === LogLevel.Debug || normalizedLevel === LogLevel.Info)) ||
|
|
147
|
-
(normalizedDefaultLogLevel === LogLevel.Info && normalizedLevel === LogLevel.Debug)
|
|
148
|
-
) {
|
|
149
|
-
return;
|
|
144
|
+
// Convert level to int if string
|
|
145
|
+
if (typeof level === 'string') {
|
|
146
|
+
level = parseInt(level, 8);
|
|
150
147
|
}
|
|
151
148
|
|
|
149
|
+
if (level < defaultLogLevel) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
|
|
152
153
|
await checkAndRotateLogFile(args);
|
|
153
154
|
|
|
154
155
|
const logPath = getLogFileURL(args);
|
|
155
156
|
const currentDate = new Date();
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
const utcFormatter = new Intl.DateTimeFormat('en-US', {
|
|
164
|
-
day: '2-digit', month: '2-digit', year: 'numeric',
|
|
165
|
-
hour: '2-digit', minute: '2-digit', second: '2-digit', timeZone: 'UTC'
|
|
166
|
-
});
|
|
167
|
-
const utcDateString = utcFormatter.format(dateUtc);
|
|
157
|
+
// Format with milliseconds manually
|
|
158
|
+
function pad(n, z = 2) { return ('00' + n).slice(-z); }
|
|
159
|
+
const localDateString = `${pad(currentDate.getDate())}-${pad(currentDate.getMonth() + 1)}-${currentDate.getFullYear()} ` +
|
|
160
|
+
`${pad(currentDate.getHours())}:${pad(currentDate.getMinutes())}:${pad(currentDate.getSeconds())}.${pad(currentDate.getMilliseconds(), 3)}`;
|
|
161
|
+
|
|
162
|
+
const utcDateString = `${pad(currentDate.getUTCDate())}-${pad(currentDate.getUTCMonth() + 1)}-${currentDate.getUTCFullYear()} ` +
|
|
163
|
+
`${pad(currentDate.getUTCHours())}:${pad(currentDate.getUTCMinutes())}:${pad(currentDate.getUTCSeconds())}.${pad(currentDate.getUTCMilliseconds(), 3)}`;
|
|
168
164
|
|
|
169
165
|
let data = `${localDateString} | UTC:${utcDateString} | ${getStringFromLevel(level)} | ${sourceClass} | ${sourceMethod} | ${message}\n`;
|
|
170
166
|
if (level === LogLevel.Error) {
|
package/src/ios/Logger.swift
CHANGED
|
@@ -5,10 +5,11 @@ import UIKit
|
|
|
5
5
|
|
|
6
6
|
private let LOG_FILE_NAME = "log.txt"
|
|
7
7
|
private let BACKUP_LOG_FILE_NAME = "log_backup.txt"
|
|
8
|
-
private let MAX_LOG_SIZE: Int64 =
|
|
9
|
-
|
|
10
|
-
private var defaultLogLevel: String = "important"
|
|
8
|
+
private let MAX_LOG_SIZE: Int64 = 10 * 1024 * 1024 // 10MB
|
|
11
9
|
|
|
10
|
+
private var defaultLogLevel: Int = 8
|
|
11
|
+
private let fileWriteQueue = DispatchQueue(label: "com.logger.filewrite", qos: .background)
|
|
12
|
+
|
|
12
13
|
@objc(logDebug:)
|
|
13
14
|
func logDebug(_ command: CDVInvokedUrlCommand) {
|
|
14
15
|
loggerWithLevel(command)
|
|
@@ -36,7 +37,7 @@ import UIKit
|
|
|
36
37
|
return
|
|
37
38
|
}
|
|
38
39
|
|
|
39
|
-
guard let level = args["level"] as?
|
|
40
|
+
guard let level = args["level"] as? Int else {
|
|
40
41
|
sendErrorResult(command.callbackId, message: "level is required")
|
|
41
42
|
return
|
|
42
43
|
}
|
|
@@ -60,9 +61,16 @@ import UIKit
|
|
|
60
61
|
try checkAndRotateLogFile(logFile: logFile, userId: userId)
|
|
61
62
|
|
|
62
63
|
let logEntry = formatLogEntry(level: level, sourceClass: sourceClass, sourceMethod: sourceMethod, message: message)
|
|
63
|
-
try appendToFile(file: logFile, data: logEntry)
|
|
64
64
|
|
|
65
|
+
// Send success result immediately without waiting for file write
|
|
65
66
|
sendSuccessResult(command.callbackId, message: "Logged to \(logFile.path)")
|
|
67
|
+
|
|
68
|
+
// Perform file write in background with silent error handling
|
|
69
|
+
appendToFile(file: logFile, data: logEntry) { error in
|
|
70
|
+
if let error = error {
|
|
71
|
+
print("Background logging error: \(error.localizedDescription)")
|
|
72
|
+
}
|
|
73
|
+
}
|
|
66
74
|
} catch {
|
|
67
75
|
sendErrorResult(command.callbackId, message: "Logging failed: \(error.localizedDescription)")
|
|
68
76
|
}
|
|
@@ -71,7 +79,7 @@ import UIKit
|
|
|
71
79
|
@objc(setLogLevel:)
|
|
72
80
|
func setLogLevel(_ command: CDVInvokedUrlCommand) {
|
|
73
81
|
guard let args = command.arguments.first as? [String: Any],
|
|
74
|
-
let level = args["level"] as?
|
|
82
|
+
let level = args["level"] as? Int else {
|
|
75
83
|
sendErrorResult(command.callbackId, message: "Invalid log level")
|
|
76
84
|
return
|
|
77
85
|
}
|
|
@@ -82,7 +90,7 @@ import UIKit
|
|
|
82
90
|
|
|
83
91
|
@objc(getLogLevel:)
|
|
84
92
|
func getLogLevel(_ command: CDVInvokedUrlCommand) {
|
|
85
|
-
sendSuccessResult(command.callbackId, message: defaultLogLevel)
|
|
93
|
+
sendSuccessResult(command.callbackId, message: "\(defaultLogLevel)")
|
|
86
94
|
}
|
|
87
95
|
|
|
88
96
|
@objc(getLogFileContent:)
|
|
@@ -188,17 +196,8 @@ import UIKit
|
|
|
188
196
|
|
|
189
197
|
// MARK: - Helper Methods
|
|
190
198
|
|
|
191
|
-
private func shouldSkipLog(level:
|
|
192
|
-
|
|
193
|
-
let normDefault = defaultLogLevel.lowercased()
|
|
194
|
-
|
|
195
|
-
if normDefault == "error" && (normLevel == "debug" || normLevel == "important") {
|
|
196
|
-
return true
|
|
197
|
-
}
|
|
198
|
-
if normDefault == "important" && normLevel == "debug" {
|
|
199
|
-
return true
|
|
200
|
-
}
|
|
201
|
-
return false
|
|
199
|
+
private func shouldSkipLog(level: Int) -> Bool {
|
|
200
|
+
return level > defaultLogLevel
|
|
202
201
|
}
|
|
203
202
|
|
|
204
203
|
private func getLogFile(userId: String) throws -> URL {
|
|
@@ -233,40 +232,54 @@ import UIKit
|
|
|
233
232
|
}
|
|
234
233
|
}
|
|
235
234
|
|
|
236
|
-
private func formatLogEntry(level:
|
|
235
|
+
private func formatLogEntry(level: Int, sourceClass: String, sourceMethod: String, message: String) -> String {
|
|
237
236
|
let dateFormatter = DateFormatter()
|
|
238
|
-
dateFormatter.dateFormat = "dd-MM-yyyy HH:mm:ss"
|
|
237
|
+
dateFormatter.dateFormat = "dd-MM-yyyy HH:mm:ss.SSS"
|
|
239
238
|
dateFormatter.locale = Locale.current
|
|
240
239
|
let localDate = dateFormatter.string(from: Date())
|
|
241
240
|
|
|
242
241
|
let utcFormatter = DateFormatter()
|
|
243
|
-
utcFormatter.dateFormat = "dd-MM-yyyy HH:mm:ss"
|
|
242
|
+
utcFormatter.dateFormat = "dd-MM-yyyy HH:mm:ss.SSS"
|
|
244
243
|
utcFormatter.timeZone = TimeZone(abbreviation: "UTC")
|
|
245
244
|
let utcDate = utcFormatter.string(from: Date())
|
|
246
|
-
|
|
247
|
-
let prefix = level
|
|
245
|
+
|
|
246
|
+
let prefix = level == 8 ? "⭕️⭕️⭕️ " : ""
|
|
248
247
|
return "\(prefix)\(localDate) | UTC:\(utcDate) | \(getStringFromLevel(level: level)) | \(sourceClass) | \(sourceMethod) | \(message)\n"
|
|
249
248
|
}
|
|
250
|
-
|
|
251
|
-
private func getStringFromLevel(level:
|
|
252
|
-
switch level
|
|
253
|
-
case
|
|
254
|
-
case
|
|
255
|
-
case
|
|
249
|
+
|
|
250
|
+
private func getStringFromLevel(level: Int) -> String {
|
|
251
|
+
switch level {
|
|
252
|
+
case 7: return "IMPORTANT"
|
|
253
|
+
case 8: return "ERROR"
|
|
254
|
+
case 9: return "DEBUG"
|
|
256
255
|
default: return ""
|
|
257
256
|
}
|
|
258
257
|
}
|
|
259
258
|
|
|
260
|
-
private func appendToFile(file: URL, data: String)
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
259
|
+
private func appendToFile(file: URL, data: String, completion: @escaping (Error?) -> Void = { _ in }) {
|
|
260
|
+
fileWriteQueue.async {
|
|
261
|
+
do {
|
|
262
|
+
let fileManager = FileManager.default
|
|
263
|
+
if !fileManager.fileExists(atPath: file.path) {
|
|
264
|
+
// Create the file if it doesn't exist
|
|
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
|
+
}
|
|
281
|
+
}
|
|
265
282
|
}
|
|
266
|
-
let fileHandle = try FileHandle(forWritingTo: file)
|
|
267
|
-
fileHandle.seekToEndOfFile()
|
|
268
|
-
fileHandle.write(data.data(using: .utf8)!)
|
|
269
|
-
fileHandle.closeFile()
|
|
270
283
|
}
|
|
271
284
|
|
|
272
285
|
private func readFile(file: URL) throws -> String {
|
package/www/logger.js
CHANGED
|
@@ -2,9 +2,9 @@ var exec = require('cordova/exec');
|
|
|
2
2
|
|
|
3
3
|
// LogLevel constants for use in Cordova apps
|
|
4
4
|
exports.LogLevel = {
|
|
5
|
-
Debug:
|
|
6
|
-
Error:
|
|
7
|
-
Info:
|
|
5
|
+
Debug: 9,
|
|
6
|
+
Error: 8,
|
|
7
|
+
Info: 7
|
|
8
8
|
};
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -34,7 +34,17 @@ exports.setLogLevel = function (level, success, error) {
|
|
|
34
34
|
if (error) error('Log level is required');
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
37
|
-
|
|
37
|
+
var logLevel = exports.LogLevel.Error;
|
|
38
|
+
|
|
39
|
+
if (level === "DEBUG") {
|
|
40
|
+
logLevel = exports.LogLevel.Debug;
|
|
41
|
+
} else if (level === "ERROR") {
|
|
42
|
+
logLevel = exports.LogLevel.Error;
|
|
43
|
+
} else if (level === "IMPORTANT") {
|
|
44
|
+
logLevel = exports.LogLevel.Info;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
exec(success, error, 'Logger', 'setLogLevel', [logLevel]);
|
|
38
48
|
};
|
|
39
49
|
|
|
40
50
|
/**
|