Open
Description
Hi.
log4js is a nice framework. I'd like to propose simpler ajax appender by using fetch API. In the following, data to be POSTed are kept as an object just before it is fetched. Therefore ObjectLayout is used.
If you like, include such capability in log4js. Thanks.
/**
* ajax by fetch appender
*/
Log4js.ObjectLayout = function(){
};
Log4js.ObjectLayout.prototype = Log4js.extend(new Log4js.Layout(), {
format: function(loggingEvent){
let useragent = "unknown";
try {
useragent = navigator.userAgent;
} catch(e){
useragent = "unknown";
}
let referer = "unknown";
try {
referer = location.href;
} catch(e){
referer = "unknown";
}
const obj = {};
obj.logger = loggingEvent.categoryName;
obj.level = loggingEvent.level.toString();
obj.message = `${loggingEvent.message}`;
obj.referer = referer;
obj.useragent = useragent;
obj.timestamp = new Date();
obj.exception = loggingEvent.exception;
return obj;
}
});
Log4js.FetchAppender = function(url){
this.isInProgress = false;
this.loggingUrl = url || "logging.log4js";
this.threshold = 1;
this.timeout = 2000;
this.loggingEventMap = new Log4js.FifoBuffer();
this.layout = new Log4js.ObjectLayout();
this.httpRequest = null;
};
Log4js.FetchAppender.prototype = Log4js.extend( new Log4js.Appender(),{
doAppend: function(loggingEvent){
log4jsLogger && log4jsLogger.trace("> FetchAppender.append");
if (this.loggingEventMap.length() <= this.threshold || this.isInProgress === true) {
this.loggingEventMap.push(loggingEvent);
}
if (this.loggingEventMap.length() >= this.threshold && this.isInProgress === false) {
//if threshold is reached send the events and reset current threshold
this.send();
}
log4jsLogger && log4jsLogger.trace("< FetchAppender.append");
},
doClear: function () {
log4jsLogger && log4jsLogger.trace("> FetchAppender.doClear");
if (this.loggingEventMap.length() > 0) {
this.send();
}
log4jsLogger && log4jsLogger.trace("< FetchAppender.doClear");
},
setThreshold: function (threshold) {
log4jsLogger && log4jsLogger.trace("> FetchAppender.setThreshold: " + threshold);
this.threshold = threshold;
log4jsLogger && log4jsLogger.trace("< FetchAppender.setThreshold");
},
setTimeout: function (milliseconds) {
this.timeout = milliseconds;
},
send: function(){
if (0 < this.loggingEventMap.length()) {
this.isInProgress = true;
const a = [];
for (var i = 0; i < this.loggingEventMap.length() && i < this.threshold; i++) {
a.push(this.layout.format(this.loggingEventMap.pull()));
}
postData(this.loggingUrl, a)
.then(data => console.log(JSON.stringify(data))) // JSON-string from `response.json()` call
.catch(error => console.error(error));
}
this.isInProgress = false;
function postData(url = ``, data = {}) {
return fetch(url, {
method: "POST",
mode: "cors", // no-cors, cors, *same-origin
cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
credentials: "same-origin", // include, same-origin, *omit
headers: {
"Content-Type": "application/json; charset=utf-8",
},
redirect: "follow",
referrer: "no-referrer",
body: JSON.stringify(data),
})
.then(response => response.json());
}
}
});
Metadata
Metadata
Assignees
Labels
No labels