1 // 3.0.2-SNAPSHOT
2 var exec = require('cordova/exec');
3
4 /**
5 * The Kapsel Logger plugin provides a Cordova plugin wrapper around the SAP Mobile Platform client logging API.
6 * <br><br>
7 *
8 * The Logger plugin has ERROR, WARN, INFO, and DEBUG log levels and log messages are captured based on the configured and selected log level.
9 * A Kapsel application can be set to these log levels by programmatic control, and by the administrator changing a setting on the server.
10 * For Android and iOS, the default log level is ERROR, so by default only ERROR level logs are captured.
11 * sap.Logger.setLogLevel() method is used to set other levels. If you want to get log messages at all log levels,
12 * you must set the log level to DEBUG. (DEBUG < INFO < WARN < ERROR) <br>
13 * If the log level is set to DEBUG, the application captures all log messages. <br>
14 * If you set the log level to INFO, the application captures INFO, WARN, and ERROR log messages. <br>
15 * If you set the log level to WARN, the application captures WARN and ERROR log messages. <br>
16 * If you set the log level to ERROR, the application captures only Error log messages.
17 * <br><br>
18 *
19 * Using the provided sap.Logger.upload() method allows developers to upload a log file to SAP Mobile Platform Server,
20 * where an administrator can view them and remotely set the appropriate log level to control the amount of information
21 * that is written to the log. When the sap.Logger.upload() method is triggered, a log file will be uploaded.
22 * If the Log Upload checkbox is selected in the Management Cockpit, the client can upload a log file by calling sap.Logger.upload().
23 * If the Log Upload checkbox is disabled in the Management Cockpit, the client does not upload the log file to the server. The attempt to upload causes an "HTTP/1.1 403 Forbidden" error.
24 * To support manual uploading of the log, you should implement a button or some other mechanism that calls sap.Logger.upload() when needed.
25 * <br>
26 * For the Logger plugin to upload a log file these conditions must be met: 1) Log Upload checkbox enabled In the Management Cockpit 2) sap.Logger.upload() is called by developer.
27 * <br>
28 * The expected work flow, with the current architecture consists of the following: <br>
29 * 1) If a user has an issue that needs to be analyzed by an administrator or developer, the user reports the issue as appropriate.<br>
30 * 2) The administrator, or developer, enables the log collection for the user on the SAP Mobile Platform server.<br>
31 * 3) The administrator lets the user know that he, or she, can upload log file. <br>
32 * 4) The user uploads thelog file to the server, and the administrator gets the uploaded log file in the Management Cockpit.<br>
33 * 5) The administrator sends the file to the developer to debug.
34 * <br><br>
35 *
36 * Currently, on iOS, if the current log level is ERROR (default level), only ERROR level messages are displayed on the console
37 * even if other log level messages are generated. But if the current log level is DEBUG, INFO, or WARN,
38 * all generated log messages, regardless of log level, are displayed on the console. <br>
39 * On Android, if the current log level is ERROR, only ERROR level messages are displayed in the Android logcat view (console).
40 * if log level is INFO, then ERROR, WARN and INFO level messages are displayed in the Android logcat view (console).
41 *
42 * When the Kapsel Settings plugin is added to the project, Settings will: 1) Get log level from the server 2) Set it into Logger on the client
43 * 3) Call sap.Logger.upload() after a logon success event, for example, when the app is launched or resumed and logon is successful.
44 * The Settings plugin retrieves the selected log level(type) from the Management Cockpit on the server,
45 * sets the log level to Logger plugin, and then automatically uploads a log file to the server.
46 * If the Settings plugin is not added to the project, a log file can be uploaded only by the developer calling the sap.Logger.upload() method manually.
47 * To upload a log file automatically, settings plugin is required.
48 * In the Management Cockpit, in the Client Logging dialog box, the Log Upload checkbox is able to enable or disable log file upload, and you can choose the log type(level).
49 * You can also view a list of the uploaded log files. On the server side, there are seven log types: NONE, FATAL, ERROR, WARNING, INFO, DEBUG and PATH.
50 * Since the Kapsel Logger plugin supports only DEBUG, INFO, WARN, and ERROR, the Logger plugin implicitly matches FATAL to ERROR, and PATH to DEBUG.
51 * If NONE is set in the Management Cockpit, Logger sets it to default log level.
52 * <br><br>
53 * <b>Adding and Removing the Logger Plugin</b><br>
54 * Add or remove the Logger plugin using the
55 * <a href="http://cordova.apache.org/docs/en/edge/guide_cli_index.md.html#The%20Command-line%20Interface">Cordova CLI</a>.<br>
56 * <br>
57 * To add the Logger plugin to your project, use the following command:<br>
58 * Cordova plugin add <path to directory containing Kapsel plugins>\logger<br>
59 * <br>
60 * To remove the Logger plugin from your project, use the following command:<br>
61 * cordova plugin rm com.sap.mp.cordova.plugins.logger
62 * <br>
63 *
64 * @namespace
65 * @alias Logger
66 * @memberof sap
67 */
68
69 Logger = function () {
70 /**
71 * Formating for message
72 * @private
73 */
74 var format = function (message) {
75 if ((message === null) || (message === undefined)) {
76 return "";
77 }
78
79 return message.toString();
80 }
81
82
83 /**
84 * Add a debug message to the log.
85 * This function logs messages with the 'DEBUG' log level.
86 *
87 * @memberof sap.Logger
88 * @method debug
89 * @param {String} message Log message to be logged.
90 * @param {String} [tag] Tag value added to the log entry used to indicate the source of the message (for example, SMP_LOGGER, SMP_AUTHPROXY).
91 * @param {function} [successCallback] Callback function called when the message has been successfully added to the log.
92 * No object will be passed to success callback.
93 * @param {function} [errorCallback] Callback function called when an error occurs while adding the message to the log.
94 * Since Kapsel Logger native code will always call the success callback function, the
95 * errorCallback function will be executed by Cordova if an error or exception occurs
96 * while making the call to the plugin.
97 * @public
98 * @memberof sap.Logger
99 * @example
100 * sap.Logger.debug("debug message", "DEBUG_TAG");
101 */
102 this.debug = function (message, tag, successCallback, errorCallback) {
103 exec(successCallback, errorCallback, "Logging", "logDebug", [format(message), tag]);
104 }
105
106 /**
107 * Add an info message to the log.
108 * This function logs messages with the 'INFO' log level.
109 *
110 * @memberof sap.Logger
111 * @method info
112 * @param {String} message Log message to be logged.
113 * @param {String} [tag] Tag value added to the log entry used to indicate the source of the message (for example, SMP_LOGGER, SMP_AUTHPROXY).
114 * @param {function} [successCallback] Callback function called when the message has been successfully added to the log.
115 * No object will be passed to success callback.
116 * @param {function} [errorCallback] Callback function called when an error occurs while adding the message to the log.
117 * Since Kapsel Logger native code will always call the success callback function, the
118 * errorCallback function will be executed by Cordova if an error or exception occurs
119 * while making the call to the plugin.
120 * @public
121 * @memberof sap.Logger
122 * @example
123 * sap.Logger.info("info message", "INFO_TAG");
124 */
125 this.info = function (message, tag, successCallback, errorCallback) {
126 exec(successCallback, errorCallback, "Logging", "logInfo", [format(message), tag]);
127 }
128
129 /**
130 * Add a warning message to the log.
131 * This function logs messages with the 'WARN' log level.
132 *
133 * @memberof sap.Logger
134 * @method warn
135 * @param {String} message Log message to be logged.
136 * @param {String} [tag] Tag value added to the log entry used to indicate the source of the message (for example, SMP_LOGGER, SMP_AUTHPROXY).
137 * @param {function} [successCallback] Callback function called when the message has been successfully added to the log.
138 * No object will be passed to success callback.
139 * @param {function} [errorCallback] Callback function called when an error occurs while adding the message to the log.
140 * Since Kapsel Logger native code will always call the success callback function, the
141 * errorCallback function will be executed by Cordova if an error/exception occurs
142 * while making the call to the plugin.
143 * @public
144 * @memberof sap.Logger
145 * @example
146 * sap.Logger.warn("warn message", "WARN_TAG");
147 */
148 this.warn = function (message, tag, successCallback, errorCallback) {
149 exec(successCallback, errorCallback, "Logging", "logWarning", [format(message), tag]);
150 }
151
152 /**
153 * Add an error message to the log.
154 * This function logs messages with the 'ERROR' log level.
155 *
156 * @memberof sap.Logger
157 * @method error
158 * @param {String} message Log message to be logged.
159 * @param {String} [tag] Tag value added to the log entry used to indicate the source of the message (for example, SMP_LOGGER, SMP_AUTHPROXY).
160 * @param {function} [successCallback] Callback function called when the message has been successfully added to the log.
161 * No object will be passed to success callback.
162 * @param {function} [errorCallback] Callback function called when an error occurs while adding the message to the log.
163 * Since Kapsel Logger native code will always call the success callback function, the
164 * errorCallback function will be executed by Cordova if an error or exception occurs
165 * while making the call to the plugin.
166 * @public
167 * @memberof sap.Logger
168 * @example
169 * sap.Logger.error("error message", "ERROR_TAG");
170 */
171 this.error = function (message, tag, successCallback, errorCallback) {
172 exec(successCallback, errorCallback, "Logging", "logError", [format(message), tag]);
173 }
174
175 /**
176 * Set log level.
177 * This function sets the log level for logging. <br>
178 * Coverage of logging data in each log level: DEBUG < INFO < WARN < ERROR. <br>
179 * Following is the expected behavior to cover log messages at specific log levels: <br>
180 * ERROR : only ERROR messages <br>
181 * WARN : ERROR and WARN messages <br>
182 * INFO : ERROR, WARN and INFO <br>
183 * DEBUG : ERROR, WARN, INFO and DEBUG <br>
184 * For example, if you want to get all log messages, you need to set the log to the 'Debug' level.
185 * If the WARN level is set, logging data contains WARN and ERROR messages. <br>
186 * Default log level is ERROR.
187 *
188 * @memberof sap.Logger
189 * @method setLogLevel
190 * @param {String} level Log level to set [DEBUG, INFO, WARN, ERROR]
191 * @param {function} [successCallback] Callback function called when the log level has been successfully set.
192 * No object will be passed to success callback.
193 * @param {function} [errorCallback] Callback function called when an error occurs while setting the log level.
194 * Since Kapsel Logger native code will always call the success callback function, the
195 * errorCallback function will be executed by Cordova if an error or exception occurs
196 * while making the call to the plugin.
197 * @memberof sap.Logger
198 * @example
199 * sap.Logger.setLogLevel(sap.Logger.DEBUG, successCallback, errorCallback);
200 *
201 * function successCallback() {
202 * alert("Log level set");
203 * }
204 *
205 * function errorCallback() {
206 * alert("Failed to set log level");
207 * }
208 */
209 this.setLogLevel = function (level, successCallback, errorCallback) {
210 if (level.toLowerCase() === "fatal")
211 level = "ERROR";
212 else if (level.toLowerCase() === "path")
213 level = "DEBUG";
214 else if (level.toLowerCase() === "warning")
215 level = "WARN";
216 else if (level.toLowerCase() === "debug")
217 level = "DEBUG";
218 else if (level.toLowerCase() === "info")
219 level = "INFO";
220 else if (level.toLowerCase() === "error")
221 level = "ERROR";
222 else if (level.toLowerCase() === "none")
223 level = "ERROR";
224
225 exec(successCallback, errorCallback, "Logging", "setLogLevel", [level]);
226 }
227
228 /**
229 * Get log level.
230 * This function gets the current log level.
231 * Use this function to know what kind of log level messages can be generated and affected at the current log level.
232 *
233 * @memberof sap.Logger
234 * @method getLogLevel
235 * @param {function} successCallback Callback function called when the log level has been successfully retrieved.
236 * When the current log level is successfully retrieved, it is fired with the current log level. [DEBUG, INFO, WARN, ERROR]
237 * Log level of String type will be passed to success callback.
238 * Default log level is ERROR.
239 * @param {function} [errorCallback] Callback function called when an error occurs while getting the current log level. For this method, error callback is optional.
240 * Since Kapsel Logger native code will always call the success callback function, the
241 * errorCallback function will be executed by Cordova if an error or exception occurs
242 * while making the call to the plugin.
243 * @memberof sap.Logger
244 * @example
245 * sap.Logger.getLogLevel(successCallback, errorCallback);
246 *
247 * function successCallback(logLevel) {
248 * alert("Log level is " + logLevel);
249 * }
250 *
251 * function errorCallback() {
252 * alert("Failed to get log level");
253 * }
254 */
255 this.getLogLevel = function(successCallback, errorCallback) {
256 exec(successCallback, errorCallback, "Logging", "getLogLevel",[]);
257 }
258
259 /**
260 * Upload a log file, with log entries, to SAP Mobile Platform server.<br>
261 * This function uploads a log file, which is helpful for collecting logging data from the app to trace bugs and issues.
262 * It uploads a log file, which contains log entries based on log level.
263 * Developers can access the log data in the Management Cockpit and/or a specific folder in installed server directly.<br><br>
264 *
265 * On iOS, the uploaded log messages are filtered by the log level at upon upload.
266 * For example, when you upload a log file with an ERROR log level, the uploaded log messages contain only ERROR log level messages.
267 * When you upload log files with an INFO level, uploaded log messages contain ERROR, WARN, and INFO log level messages.
268 *
269 * <br><br>
270 * On Android, generated log messages are filtered "at the log level."
271 * In other words, the already generated and filtered log messages at another log level are not affected by the current log level.
272 * Log messages are not filtered upon upload. For example, if you set the log level to DEBUG log messages are filtered at four levels (DEBUG, INFO, WARN, and ERROR.
273 * Logger on Android has four log levels messages. So, if you set the log level to WARN and upload a log file, the log file has four log level messages that were already generated at the DEBUG level.
274 *
275 * @memberof sap.Logger
276 * @method upload
277 * @param {function} successCallback Callback function called when a log file is successfully uploaded to the server.
278 * When a log file is successfully uploaded, it is fired. (with http statusCode and statusMessage for success)
279 * @param {function} errorCallback Callback function called when an error occurs while uploading a log file to the server.
280 * If there is a connectivity error, such as an HTTP error, or unknown server error,
281 * it is fired with http statusCode and statusMessage for error.
282 * @public
283 * @memberof sap.Logger
284 * @example
285 * sap.Logger.upload(successCallback, errorCallback);
286 *
287 * function successCallback() {
288 * alert("Upload Successful");
289 * }
290 *
291 * function errorCallback(e) {
292 * alert("Upload Failed. Status: " + e.statusCode + ", Message: " + e.statusMessage);
293 * }
294 */
295 this.upload = function (successCallback, errorCallback) {
296 sap.Logon.core.getState (function (result) {
297 if(result.status === "new") {
298 errorCallback({statusCode : 0, statusMessage : "Logon in " + result.status + " state. Registration is required!!"});
299 } else {
300 sap.Logon.unlock(function (connectionInfo) {
301 //Add application ID required for REST call
302 connectionInfo.applicationId = sap.Logon.applicationId;
303 exec(successCallback, errorCallback, "Logging", "uploadLog", [connectionInfo]);
304 }, function () {
305 errorCallback({statusCode : 0, statusMessage : "Logon failed"});
306 });
307 }
308 },
309 function (){
310 errorCallback({statusCode : 0, statusMessage : "Failed to get current logon state."});
311 }
312 );
313 }
314 }
315
316 /**
317 * Constant variable for Error log level. It contains "ERROR" string.
318 * @memberof sap.Logger
319 * @constant
320 * @type String
321 * @example
322 * sap.Logger.setLogLevel(sap.Logger.ERROR);
323 */
324 Logger.prototype.ERROR = "ERROR";
325
326 /**
327 * Constant variable for Warning log level. It contains "WARN" string.
328 * @memberof sap.Logger
329 * @constant
330 * @type String
331 * @example
332 * sap.Logger.setLogLevel(sap.Logger.WARN);
333 */
334 Logger.prototype.WARN = "WARN";
335
336 /**
337 * Constant variable for Information log level. It contains "INFO" string.
338 * @memberof sap.Logger
339 * @constant
340 * @type String
341 * @example
342 * sap.Logger.setLogLevel(sap.Logger.INFO);
343 */
344 Logger.prototype.INFO = "INFO";
345
346 /**
347 * Constant variable for Debug log level. It contains "DEBUG" string.
348 * @memberof sap.Logger
349 * @constant
350 * @type String
351 * @example
352 * sap.Logger.setLogLevel(sap.Logger.DEBUG);
353 */
354 Logger.prototype.DEBUG = "DEBUG";
355
356 module.exports = new Logger();
357