kopia lustrzana https://github.com/OpenDroneMap/NodeODM
Config + logging
* Use a config file for making things like logging options and port variable * Use log file for internal + express (morgan) loggingpull/1/head
rodzic
e898236d17
commit
6e3624d5f8
|
@ -0,0 +1,35 @@
|
|||
'use strict';
|
||||
|
||||
// config.js - Configuration for cognicity-server
|
||||
|
||||
/**
|
||||
* Cognicity server configuration object.
|
||||
* @namespace {object} config
|
||||
* @property {string} instance The name of this instance of the server
|
||||
* @property {object} logger Configuration options for logging
|
||||
* @property {string} logger.level Log level - info, verbose or debug are most useful. Levels are (npm defaults): silly, debug, verbose, info, warn, error.
|
||||
* @property {number} logger.maxFileSize Maximum size of each log file in bytes
|
||||
* @property {number} logger.maxFiles Maximum number of log files to keep
|
||||
* @property {?number} logger.logDirectory Full path to directory to store log files in, if not set logs will be written to the application directory
|
||||
* @property {number} port Port to launch server on
|
||||
*/
|
||||
|
||||
var config = {};
|
||||
|
||||
// Instance name - default name for this configuration (will be server process name)
|
||||
config.instance = 'node-OpenDroneMap';
|
||||
|
||||
|
||||
// Logging configuration
|
||||
config.logger = {};
|
||||
config.logger.level = "debug"; // What level to log at; info, verbose or debug are most useful. Levels are (npm defaults): silly, debug, verbose, info, warn, error.
|
||||
config.logger.maxFileSize = 1024 * 1024 * 100; // Max file size in bytes of each log file; default 100MB
|
||||
config.logger.maxFiles = 10; // Max number of log files kept
|
||||
config.logger.logDirectory = ''; // Set this to a full path to a directory - if not set logs will be written to the application directory.
|
||||
|
||||
// Server port
|
||||
config.port = process.env.PORT || 8081;
|
||||
// process.env.PORT is what AWS Elastic Beanstalk defines
|
||||
// on IBM bluemix use config.port = process.env.VCAP_APP_PORT || 8081;
|
||||
|
||||
module.exports = config;
|
61
index.js
61
index.js
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Node-OpenDroneMap Node.js App and REST API to access OpenDroneMap.
|
||||
/*
|
||||
Node-OpenDroneMap Node.js App and REST API to access OpenDroneMap.
|
||||
Copyright (C) 2016 Node-OpenDroneMap Contributors
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
@ -17,7 +17,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/
|
||||
"use strict";
|
||||
|
||||
var config = require('./config.js')
|
||||
|
||||
let logger = require('winston');
|
||||
let fs = require('fs');
|
||||
let path = require('path');
|
||||
let async = require('async');
|
||||
|
||||
let express = require('express');
|
||||
|
@ -27,10 +31,41 @@ let addRequestId = require('./libs/expressRequestId')();
|
|||
let multer = require('multer');
|
||||
let bodyParser = require('body-parser');
|
||||
let morgan = require('morgan');
|
||||
|
||||
// Set up logging
|
||||
// Configure custom File transport to write plain text messages
|
||||
var logPath = ( config.logger.logDirectory ? config.logger.logDirectory : __dirname );
|
||||
// Check that log file directory can be written to
|
||||
try {
|
||||
fs.accessSync(logPath, fs.W_OK);
|
||||
} catch (e) {
|
||||
console.log( "Log directory '" + logPath + "' cannot be written to" );
|
||||
throw e;
|
||||
}
|
||||
logPath += path.sep;
|
||||
logPath += config.instance + ".log";
|
||||
|
||||
logger
|
||||
.add(logger.transports.File, {
|
||||
filename: logPath, // Write to projectname.log
|
||||
json: false, // Write in plain text, not JSON
|
||||
maxsize: config.logger.maxFileSize, // Max size of each file
|
||||
maxFiles: config.logger.maxFiles, // Max number of files
|
||||
level: config.logger.level // Level of log messages
|
||||
})
|
||||
// Console transport is no use to us when running as a daemon
|
||||
.remove(logger.transports.Console);
|
||||
|
||||
var winstonStream = {
|
||||
write: function(message, encoding){
|
||||
logger.info(message.slice(0, -1));
|
||||
}
|
||||
};
|
||||
|
||||
let TaskManager = require('./libs/taskManager');
|
||||
let Task = require('./libs/Task');
|
||||
|
||||
app.use(morgan('tiny'));
|
||||
app.use(morgan('combined', { stream : winstonStream }));
|
||||
app.use(bodyParser.urlencoded({extended: true}));
|
||||
app.use(bodyParser.json());
|
||||
app.use(express.static('public'));
|
||||
|
@ -54,13 +89,13 @@ let upload = multer({
|
|||
}
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
app.post('/task/new', addRequestId, upload.array('images'), (req, res) => {
|
||||
if (req.files.length === 0) res.json({error: "Need at least 1 file."});
|
||||
else{
|
||||
// Move to data
|
||||
async.series([
|
||||
cb => {
|
||||
cb => {
|
||||
fs.stat(`data/${req.id}`, (err, stat) => {
|
||||
if (err && err.code === 'ENOENT') cb();
|
||||
else cb(new Error(`Directory exists (should not have happened: ${err.code})`));
|
||||
|
@ -140,16 +175,16 @@ app.post('/task/restart', uuidCheck, (req, res) => {
|
|||
let gracefulShutdown = done => {
|
||||
async.series([
|
||||
cb => { taskManager.dumpTaskList(cb) },
|
||||
cb => {
|
||||
console.log("Closing server");
|
||||
cb => {
|
||||
logger.info("Closing server");
|
||||
server.close();
|
||||
console.log("Exiting...");
|
||||
logger.info("Exiting...");
|
||||
process.exit(0);
|
||||
}
|
||||
], done);
|
||||
};
|
||||
|
||||
// listen for TERM signal .e.g. kill
|
||||
// listen for TERM signal .e.g. kill
|
||||
process.on ('SIGTERM', gracefulShutdown);
|
||||
|
||||
// listen for INT signal e.g. Ctrl-C
|
||||
|
@ -160,12 +195,12 @@ let taskManager;
|
|||
let server;
|
||||
|
||||
async.series([
|
||||
cb => { taskManager = new TaskManager(cb); },
|
||||
cb => { server = app.listen(3000, err => {
|
||||
if (!err) console.log('Server has started on port 3000');
|
||||
cb => { taskManager = new TaskManager(cb,logger); },
|
||||
cb => { server = app.listen(config.port, err => {
|
||||
if (!err) logger.info('Server has started on port ' + String(config.port));
|
||||
cb(err);
|
||||
});
|
||||
}
|
||||
], err => {
|
||||
if (err) console.log("Error during startup: " + err.message);
|
||||
if (err) logger.error("Error during startup: " + err.message);
|
||||
});
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Node-OpenDroneMap Node.js App and REST API to access OpenDroneMap.
|
||||
/*
|
||||
Node-OpenDroneMap Node.js App and REST API to access OpenDroneMap.
|
||||
Copyright (C) 2016 Node-OpenDroneMap Contributors
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
@ -28,7 +28,8 @@ const TASKS_DUMP_FILE = "data/tasks.json";
|
|||
const CLEANUP_TASKS_IF_OLDER_THAN = 1000 * 60 * 60 * 24 * 3; // 3 days
|
||||
|
||||
module.exports = class TaskManager{
|
||||
constructor(done){
|
||||
constructor(done,logger){
|
||||
this.logger = logger;
|
||||
this.tasks = {};
|
||||
this.runningQueue = [];
|
||||
|
||||
|
@ -48,30 +49,30 @@ module.exports = class TaskManager{
|
|||
|
||||
cb();
|
||||
}
|
||||
], done);
|
||||
], done);
|
||||
}
|
||||
|
||||
// Removes old tasks that have either failed, are completed, or
|
||||
// Removes old tasks that have either failed, are completed, or
|
||||
// have been canceled.
|
||||
removeOldTasks(done){
|
||||
let list = [];
|
||||
let now = new Date().getTime();
|
||||
console.log("Checking for old tasks to be removed...");
|
||||
this.logger.info("Checking for old tasks to be removed...");
|
||||
|
||||
for (let uuid in this.tasks){
|
||||
let task = this.tasks[uuid];
|
||||
|
||||
if ([statusCodes.FAILED,
|
||||
statusCodes.COMPLETED,
|
||||
statusCodes.CANCELED].indexOf(task.status.code) !== -1 &&
|
||||
if ([statusCodes.FAILED,
|
||||
statusCodes.COMPLETED,
|
||||
statusCodes.CANCELED].indexOf(task.status.code) !== -1 &&
|
||||
now - task.dateCreated > CLEANUP_TASKS_IF_OLDER_THAN){
|
||||
list.push(task.uuid);
|
||||
}
|
||||
}
|
||||
|
||||
async.eachSeries(list, (uuid, cb) => {
|
||||
console.log(`Cleaning up old task ${uuid}`)
|
||||
this.remove(uuid, cb);
|
||||
async.eachSeries(list, (uuid, cb) => {
|
||||
this.logger.info(`Cleaning up old task ${uuid}`)
|
||||
this.remove(uuid, cb);
|
||||
}, done);
|
||||
}
|
||||
|
||||
|
@ -90,11 +91,11 @@ module.exports = class TaskManager{
|
|||
}
|
||||
});
|
||||
}, err => {
|
||||
console.log(`Initialized ${tasks.length} tasks`);
|
||||
this.logger.info(`Initialized ${tasks.length} tasks`);
|
||||
if (done !== undefined) done();
|
||||
});
|
||||
});
|
||||
}else{
|
||||
console.log("No tasks dump found");
|
||||
this.logger.info("No tasks dump found");
|
||||
if (done !== undefined) done();
|
||||
}
|
||||
});
|
||||
|
@ -135,7 +136,7 @@ module.exports = class TaskManager{
|
|||
|
||||
removeFromRunningQueue(task){
|
||||
assert(task.constructor.name === "Task", "Must be a Task object");
|
||||
|
||||
|
||||
this.runningQueue = this.runningQueue.filter(t => {
|
||||
return t !== task;
|
||||
});
|
||||
|
@ -213,9 +214,9 @@ module.exports = class TaskManager{
|
|||
}
|
||||
|
||||
fs.writeFile(TASKS_DUMP_FILE, JSON.stringify(output), err => {
|
||||
if (err) console.log(`Could not dump tasks: ${err.message}`);
|
||||
else console.log("Dumped tasks list.");
|
||||
if (err) this.logger.error(`Could not dump tasks: ${err.message}`);
|
||||
else this.logger.debug("Dumped tasks list.");
|
||||
if (done !== undefined) done();
|
||||
})
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
@ -28,7 +28,8 @@
|
|||
"multer": "^1.1.0",
|
||||
"node-schedule": "^1.1.1",
|
||||
"node-uuid": "^1.4.7",
|
||||
"rimraf": "^2.5.3"
|
||||
"rimraf": "^2.5.3",
|
||||
"winston": "^2.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"nodemon": "^1.9.2"
|
||||
|
|
Ładowanie…
Reference in New Issue