├── MMM-syslog.js
├── README.md
└── node_helper.js
/MMM-syslog.js:
--------------------------------------------------------------------------------
1 | /* global Module */
2 |
3 | /* Magic Mirror
4 | * Module: MMM-syslog
5 | *
6 | * By Paul-Vincent Roll http://paulvincentroll.com
7 | * MIT Licensed.
8 | */
9 |
10 | Module.register('MMM-syslog',{
11 |
12 | messages: [],
13 |
14 | defaults: {
15 | max: 5,
16 | format: false,
17 | types: {
18 | INFO: "dimmed",
19 | WARNING: "normal",
20 | ERROR: "bright"
21 | },
22 | icons: {
23 | INFO: "info",
24 | WARNING: "exclamation",
25 | ERROR: "exclamation-triangle"
26 | },
27 | shortenMessage: false,
28 | alert: true
29 | },
30 |
31 | getStyles: function () {
32 | return ["font-awesome.css"];
33 | },
34 |
35 | getScripts: function() {
36 | return ["moment.js"];
37 | },
38 |
39 | start: function() {
40 | this.sendSocketNotification("CONNECT", {max: this.config.max, logFile: this.file('logs.json')});
41 | Log.info("Starting module: " + this.name);
42 | moment.locale(config.language);
43 |
44 | //Update DOM every minute so that the time of the call updates and calls get removed after a certain time
45 | setInterval(() => {
46 | this.updateDom();
47 | }, 60000);
48 | },
49 |
50 | socketNotificationReceived: function(notification, payload) {
51 | if(notification === "NEW_MESSAGE"){
52 | if (this.config.alert && !payload.silent) {
53 | this.sendNotification("SHOW_ALERT", {type: "notification", title: payload.type, message: payload.message});
54 | }
55 | this.messages.push(payload);
56 | while(this.messages.length > this.config.max){
57 | this.messages.shift();
58 | }
59 | this.updateDom(3000);
60 | }
61 | },
62 |
63 | getDom: function() {
64 |
65 | var wrapper = document.createElement("div");
66 | if(this.config.title !== false){
67 | var title = document.createElement("header");
68 | title.innerHTML = this.config.title || this.name;
69 | wrapper.appendChild(title);
70 | }
71 | var logs = document.createElement("table");
72 |
73 | for (var i = this.messages.length - 1; i >= 0; i--) {
74 | //Create callWrapper
75 | var callWrapper = document.createElement("tr");
76 | callWrapper.classList.add("normal");
77 |
78 | var iconCell = document.createElement("td");
79 | var icon = document.createElement("i");
80 | if(this.config.icons.hasOwnProperty(this.messages[i].type)){
81 | icon.classList.add("fa", "fa-fw", "fa-" + this.config.icons[this.messages[i].type]);
82 | }
83 | else {
84 | icon.classList.add("fa", "fa-fw", "fa-question");
85 | }
86 | if(this.config.types.hasOwnProperty(this.messages[i].type)){
87 | icon.classList.add(this.config.types[this.messages[i].type]);
88 | }
89 |
90 | iconCell.classList.add("small");
91 |
92 | iconCell.appendChild(icon);
93 | callWrapper.appendChild(iconCell);
94 |
95 | var message = this.messages[i].message;
96 | if(this.config.shortenMessage && message.length > this.config.shortenMessage){
97 | message = message.slice(0, this.config.shortenMessage) + "…";
98 | }
99 | //Set caller of row
100 | var caller = document.createElement("td");
101 | caller.innerHTML = " " + message;
102 | caller.classList.add("title", "small", "align-left");
103 | if(this.config.types.hasOwnProperty(this.messages[i].type)){
104 | caller.classList.add(this.config.types[this.messages[i].type]);
105 | }
106 | callWrapper.appendChild(caller);
107 |
108 | //Set time of row
109 | var time = document.createElement("td");
110 | time.innerHTML = this.config.format ? moment(this.messages[i].timestamp).format(this.config.format) : moment(this.messages[i].timestamp).fromNow();
111 | time.classList.add("time", "light", "xsmall");
112 | callWrapper.appendChild(time);
113 |
114 | //Add to logs
115 | logs.appendChild(callWrapper);
116 | }
117 | wrapper.appendChild(logs);
118 | return wrapper;
119 | }
120 | });
121 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MMM-syslog
2 | Notification API Module for MagicMirror2
3 |
4 | ## Example
5 |
6 | 
7 |
8 | ## Dependencies
9 | * An installation of [MagicMirror2](https://github.com/MichMich/MagicMirror)
10 |
11 | ## Installation
12 | 1. Clone this repo into `~/MagicMirror/modules` directory.
13 | 2. Configure your `~/MagicMirror/config/config.js`:
14 |
15 | ```
16 | {
17 | module: 'MMM-syslog',
18 | position: 'top_right',
19 | config: {
20 | ...
21 | }
22 | }
23 | ```
24 |
25 | ## Config Options
26 | | **Option** | **Default** | **Description** |
27 | | --- | --- | --- |
28 | | `max` | `5` | How many messages should be displayed on the screen. |
29 | | `format` | `false` | Displays relative date format, for absolute date format provide a string like `'DD:MM HH:mm'` [All Options](http://momentjs.com/docs/#/displaying/format/) |
30 | | `types` | `{INFO: "dimmed", WARNING: "normal", ERROR: "bright"}` | Object with message types and their css class. |
31 | | `shortenMessage` | `false` | After how many characters the message should be cut. Default: show all. |
32 | | `alert` | `true` | Display notification? |
33 |
34 | ## How to Use
35 | Make an http get request like:
36 | http://MIRROR_IP:MIRROR_PORT/syslog?type=INFO&message=YOUR_MESSAGE&silent=true : no notification
37 |
38 |
--------------------------------------------------------------------------------
/node_helper.js:
--------------------------------------------------------------------------------
1 | /* global Module */
2 |
3 | /* Magic Mirror
4 | * Module: MMM-syslog
5 | *
6 | * By Paul-Vincent Roll http://paulvincentroll.com
7 | * MIT Licensed.
8 | */
9 |
10 | const NodeHelper = require("node_helper");
11 | const url = require("url");
12 | const fs = require("fs");
13 |
14 | module.exports = NodeHelper.create({
15 |
16 | start: function() {
17 | this.expressApp.get('/syslog', (req, res) => {
18 |
19 | var query = url.parse(req.url, true).query;
20 | var message = query.message;
21 | var type = query.type;
22 | var silent = query.silent || false;
23 |
24 | if (message == null && type == null){
25 | res.send({"status": "failed", "error": "No message and type given."});
26 | }
27 | else if (message == null){
28 | res.send({"status": "failed", "error": "No message given."});
29 | }
30 | else if (type == null) {
31 | res.send({"status": "failed", "error": "No type given."});
32 | }
33 | else {
34 | var log = {"type": type, "message": message, "silent": silent, "timestamp": new Date()};
35 | res.send({"status": "success", "payload": log});
36 | this.sendSocketNotification("NEW_MESSAGE", log);
37 | this.storeLog(log);
38 | }
39 | });
40 | },
41 |
42 | socketNotificationReceived: function(notification, payload) {
43 | if(notification === "CONNECT"){
44 | this.logFile = payload.logFile;
45 | this.loadLogs();
46 | this.max = payload.max;
47 | }
48 | },
49 |
50 | storeLog: function(log){
51 | this.logs.push(log);
52 | while(this.logs.length > this.max){
53 | this.logs.shift();
54 | }
55 | fs.writeFileSync(this.logFile, JSON.stringify({"messages": this.logs}), 'utf8');
56 | },
57 |
58 | loadLogs: function(){
59 | if(this.fileExists(this.logFile)){
60 | this.logs = JSON.parse(fs.readFileSync(this.logFile, 'utf8')).messages;
61 | for(var i = 0; i < this.logs.length; i++){
62 | this.sendSocketNotification("NEW_MESSAGE", this.logs[i]);
63 | }
64 | } else {
65 | this.logs = [];
66 | }
67 | },
68 |
69 | fileExists: function(path){
70 | try {
71 | return fs.statSync(path).isFile();
72 | } catch(e) {
73 | console.log("No log file found.");
74 | return false;
75 | }
76 | }
77 |
78 | });
--------------------------------------------------------------------------------