Skip to content

Commit

Permalink
add support for logging all about from plugins etc, rename logging_in…
Browse files Browse the repository at this point in the history
…dex.html to index.html, then restart, output logged to smart-mirror.log, new file on each startup
  • Loading branch information
sdetweil committed Jun 12, 2020
1 parent f4cfaf4 commit c028538
Show file tree
Hide file tree
Showing 2 changed files with 190 additions and 0 deletions.
106 changes: 106 additions & 0 deletions app/js/logger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*global window */
const winston = require("winston");
const prettyMs = require("pretty-ms");

/**
* Proxy the standard 'console' object and redirect it toward a logger.
*/
class Logger {
constructor({ fn = "./smart-mirror.log" } = {}) {
// Retain a reference to the original console
this.originalConsole = window.console;
this.timers = new Map([]);

// Configure a logger
//let fn = './smart-mirror.log' // `${require('electron').remote.app.getPath('userData')}/logs/downloader.log`
this.logger = winston.createLogger({
level: "info",
format: winston.format.combine(
winston.format.timestamp(),
winston.format.printf(({ level, message, timestamp }) => {
return `${timestamp} ${level}: ${message}`;
})
),
transports: [
new winston.transports.File({
filename: fn, // Note: require('electron').remote is undefined when I include it in the normal imports
handleExceptions: true, // Log unhandled exceptions
maxsize: 1048576, // 10 MB
maxFiles: 10,
}),
],
});
this.logger = winston.createLogger({
level: "debug",
format: winston.format.combine(
winston.format.timestamp(),
winston.format.printf(({ level, message, timestamp }) => {
return `${timestamp} ${level}: ${message}`;
})
),
transports: [
new winston.transports.File({
filename: fn, // Note: require('electron').remote is undefined when I include it in the normal imports
handleExceptions: true, // Log unhandled exceptions
maxsize: 1048576, // 10 MB
maxFiles: 10,
}),
],
});

const _this = this;

// Switch out the console with a proxied version
window.console = new Proxy(this.originalConsole, {
// Override the console functions
get(target, property) {
// Leverage the identical logger functions
if (["debug", "info", "warn", "error"].includes(property))
return (...parameters) => {
_this.logger[property](parameters);
// Simple approach to logging to console. Initially considered
// using a custom logger. But this is much easier to implement.
// Downside is that the format differs but I can live with that
_this.originalConsole[property](...parameters);
};
// The log function differs in logger so map it to info
if ("log" === property)
return (...parameters) => {
_this.logger.info(parameters);
_this.originalConsole.info(...parameters);
};
// Re-implement the time and timeEnd functions
if ("time" === property)
return (label) =>
_this.timers.set(label, window.performance.now());
if ("timeEnd" === property)
return (label) => {
const now = window.performance.now();
if (!_this.timers.has(label)) {
_this.logger.warn(
`console.timeEnd('${label}') called without preceding console.time('${label}')! Or console.timeEnd('${label}') has been called more than once.`
);
}
const timeTaken = prettyMs(
now - _this.timers.get(label)
);
_this.timers.delete(label);
const message = `${label} ${timeTaken}`;
_this.logger.info(message);
_this.originalConsole.info(message);
};

// Any non-overriden functions are passed to console
return target[property];
},
});
}
}

/**
* Calling this function switches the window.console for a proxied version.
* The proxy allows us to redirect the call to a logger.
*/
function switchConsoleToLogger(n) {
new Logger({ fn: n });
} // eslint-disable-line no-unused-vars
84 changes: 84 additions & 0 deletions logging_index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<!DOCTYPE html>
<html ng-app="SmartMirror">

<head ng-controller="Theme">
<meta charset="utf-8">
<title>Smart Mirror</title>
<script src="app/js/logger.js"></script>
<script>switchConsoleToLogger()</script>
<script>
const annyang = require('annyang')
const fs = require('fs')
let config
try{
config = require('./config.json')
} catch (e){
config = require('./remote/.config.default.json')
}
// Error logging
window.onerror = function (errorMsg, url, lineNumber) {
fs.appendFileSync('./smart-mirror.log', '['+ new Date().toString() + '] '
+ errorMsg + '| Script: ' + url + ' Line: ' + lineNumber + '\n');
}
</script>


<!-- Styles and Resources -->
<link rel="shortcut icon" href="favicon.ico" />
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,800,700' rel='stylesheet' type='text/css'>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="stylesheet" ng-href="app/css/{{ layoutName }}.css" />
<!-- bower:css -->
<!-- endbower -->

</head>

<body ng-controller="MirrorCtrl" ng-cloak>
<div class="fullscreen below">
</div>
<div class="top">
<div class="top-left">
</div>
<div class="top-right">
</div>
</div>
<div class="container" ng-class="(listening == true)?'listening':'not-listening'">
<div class="middle-center">
</div>
<div class="bottom-center">
<div class="error" ng-bind="speechError" ng-show="speechError"></div>
<div class="partial-result" ng-bind="partialResult" ng-hide="speechError"></div>
</div>
<div class="bottom-left">
</div>
<div class="bottom-right">
<!-- Someday something will live here -->
</div>
</div>
<div ng-show="focus == 'sleep'" class="sleep-cover fade"></div>
<!-- Smart Mirror JS
==========================================================================
The good stuff. -->

<!-- bower:js -->
<script src="bower_components/moment/min/moment-with-locales.js"></script>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-animate/angular-animate.js"></script>
<script src="bower_components/angular-dynamic-locale/dist/tmhDynamicLocale.js"></script>
<script src="bower_components/angular-translate/angular-translate.js"></script>
<script src="bower_components/angular-translate-loader-static-files/angular-translate-loader-static-files.js"></script>
<script src="bower_components/rrule/lib/rrule.js"></script>
<script src="bower_components/skycons/skycons.js"></script>
<!-- endbower -->

<script src="https://connect.soundcloud.com/sdk/sdk-3.0.0.js"></script>

<!-- App -->

<script src="app/js/app.js"></script>
<script src="app/js/focus.js"></script>
<script src="app/js/themeController.js"></script>
<!-- main page -->
</body>

</html>

0 comments on commit c028538

Please sign in to comment.