mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
Adding node.js server
This commit is contained in:
parent
26fed84187
commit
e6d17d0641
12 changed files with 359 additions and 0 deletions
69
src/server/app.js
Normal file
69
src/server/app.js
Normal file
|
@ -0,0 +1,69 @@
|
|||
var express = require('express');
|
||||
var path = require('path');
|
||||
var favicon = require('serve-favicon');
|
||||
var logger = require('morgan');
|
||||
var cookieParser = require('cookie-parser');
|
||||
var bodyParser = require('body-parser');
|
||||
var compression = require('compression');
|
||||
var config = require('./config');
|
||||
|
||||
var routes = require('./routes/index');
|
||||
var proxy = require('./routes/proxy');
|
||||
|
||||
var app = express();
|
||||
|
||||
// view engine setup
|
||||
app.set('views', path.join(__dirname, 'views'));
|
||||
app.set('view engine', 'jade');
|
||||
|
||||
// uncomment after placing your favicon in /public
|
||||
//app.use(favicon(__dirname + '/public/favicon.ico'));
|
||||
app.use(logger('dev'));
|
||||
|
||||
// The proxy must be set up before all the other middleware.
|
||||
// TODO: WE might want to move the middleware to each of the individual routes
|
||||
// so we don't have weird conflicts in the future.
|
||||
app.use('/elasticsearch', proxy);
|
||||
|
||||
app.use(bodyParser.json());
|
||||
app.use(bodyParser.urlencoded({ extended: false }));
|
||||
app.use(cookieParser());
|
||||
app.use(compression());
|
||||
// app.use(require('less-middleware')(config.public_folder));
|
||||
app.use(express.static(config.public_folder));
|
||||
|
||||
app.use('/', routes);
|
||||
|
||||
// catch 404 and forward to error handler
|
||||
app.use(function (req, res, next) {
|
||||
var err = new Error('Not Found');
|
||||
err.status = 404;
|
||||
next(err);
|
||||
});
|
||||
|
||||
// error handlers
|
||||
|
||||
// development error handler
|
||||
// will print stacktrace
|
||||
if (app.get('env') === 'development') {
|
||||
app.use(function (err, req, res, next) {
|
||||
res.status(err.status || 500);
|
||||
res.render('error', {
|
||||
message: err.message,
|
||||
error: err
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// production error handler
|
||||
// no stacktraces leaked to user
|
||||
app.use(function (err, req, res, next) {
|
||||
res.status(err.status || 500);
|
||||
res.render('error', {
|
||||
message: err.message,
|
||||
error: {}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
module.exports = app;
|
65
src/server/bin/kibana.js
Executable file
65
src/server/bin/kibana.js
Executable file
|
@ -0,0 +1,65 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var app = require('../app');
|
||||
var debug = require('debug')('node-server:server');
|
||||
var http = require('http');
|
||||
var config = require('../config');
|
||||
|
||||
/**
|
||||
* Get port from environment and store in Express.
|
||||
*/
|
||||
|
||||
var port = parseInt(process.env.PORT, 10) || config.port || 3000;
|
||||
var host = process.env.HOST || config.host || '127.0.0.1';
|
||||
app.set('port', port);
|
||||
|
||||
/**
|
||||
* Create HTTP server.
|
||||
*/
|
||||
|
||||
var server = http.createServer(app);
|
||||
|
||||
/**
|
||||
* Listen on provided port, on all network interfaces.
|
||||
*/
|
||||
|
||||
server.listen(port, host);
|
||||
server.on('error', onError);
|
||||
server.on('listening', onListening);
|
||||
|
||||
/**
|
||||
* Event listener for HTTP server "error" event.
|
||||
*/
|
||||
|
||||
function onError(error) {
|
||||
if (error.syscall !== 'listen') {
|
||||
throw error;
|
||||
}
|
||||
|
||||
// handle specific listen errors with friendly messages
|
||||
switch (error.code) {
|
||||
case 'EACCES':
|
||||
console.error('Port ' + port + ' requires elevated privileges');
|
||||
process.exit(1);
|
||||
break;
|
||||
case 'EADDRINUSE':
|
||||
console.error('Port ' + port + ' is already in use');
|
||||
process.exit(1);
|
||||
break;
|
||||
default:
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Event listener for HTTP server "listening" event.
|
||||
*/
|
||||
|
||||
function onListening() {
|
||||
var address = server.address();
|
||||
debug('Listening on ' + address.address + ':' + address.port);
|
||||
}
|
27
src/server/config/index.js
Normal file
27
src/server/config/index.js
Normal file
|
@ -0,0 +1,27 @@
|
|||
var _ = require('lodash');
|
||||
var fs = require('fs');
|
||||
var yaml = require('js-yaml');
|
||||
var path = require('path');
|
||||
var listPlugins = require('../lib/listPlugins');
|
||||
var configPath = process.env.CONFIG_PATH || path.join(__dirname, 'kibana.yml');
|
||||
var kibana = yaml.safeLoad(fs.readFileSync(configPath, 'utf8'));
|
||||
var env = process.env.NODE_ENV || 'development';
|
||||
|
||||
var public_folder = path.resolve(__dirname, '..', '..', 'kibana');
|
||||
if (env !== 'development') {
|
||||
public_folder = path.resolve(__dirname, '..', 'public');
|
||||
}
|
||||
|
||||
var config = module.exports = {
|
||||
port : kibana.port || 5601,
|
||||
host : kibana.host || '0.0.0.0',
|
||||
elasticsearch : kibana.elasticsearch_url || 'http : //localhost : 9200',
|
||||
root : path.normalize(path.join(__dirname, '..')),
|
||||
quiet : false,
|
||||
public_folder : public_folder,
|
||||
external_plugins_folder : process.env.PLUGINS_FOLDER || null,
|
||||
bundled_plugins_folder : path.resolve(public_folder, 'plugins'),
|
||||
kibana : kibana
|
||||
};
|
||||
|
||||
config.plugins = listPlugins(config);
|
38
src/server/config/kibana.yml
Normal file
38
src/server/config/kibana.yml
Normal file
|
@ -0,0 +1,38 @@
|
|||
# Kibana is served by a back end server. This controls which port to use.
|
||||
port: 5601
|
||||
|
||||
# The host to bind the server to.
|
||||
host: "0.0.0.0"
|
||||
|
||||
# The Elasticsearch instance to use for all your queries.
|
||||
elasticsearch_url: "http://localhost:9200"
|
||||
|
||||
# If your Elasticsearch is protected with basic auth:
|
||||
# elasticsearch_username: user
|
||||
# elasticsearch_password: pass
|
||||
|
||||
# preserve_elasticsearch_host true will send the hostname specified in `elasticsearch`. If you set it to false,
|
||||
# then the host you use to connect to *this* Kibana instance will be sent.
|
||||
elasticsearch_preserve_host: true
|
||||
|
||||
# Kibana uses an index in Elasticsearch to store saved searches, visualizations
|
||||
# and dashboards. It will create a new index if it doesn't already exist.
|
||||
kibana_index: ".kibana"
|
||||
|
||||
# The default application to load.
|
||||
default_app_id: "discover"
|
||||
|
||||
# Time in seconds to wait for responses from the back end or elasticsearch.
|
||||
# Note this should always be higher than "shard_timeout".
|
||||
# This must be > 0
|
||||
request_timeout: 60
|
||||
|
||||
# Time in milliseconds for Elasticsearch to wait for responses from shards.
|
||||
# Note this should always be lower than "request_timeout".
|
||||
# Set to 0 to disable (not recommended).
|
||||
shard_timeout: 30000
|
||||
|
||||
# Set to false to have a complete disregard for the validity of the SSL
|
||||
# certificate.
|
||||
verify_ssl: true
|
||||
|
18
src/server/lib/listPlugins.js
Normal file
18
src/server/lib/listPlugins.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
var _ = require('lodash');
|
||||
var glob = require('glob');
|
||||
var path = require('path');
|
||||
|
||||
var plugins = function (dir) {
|
||||
if (!dir) return [];
|
||||
var files = glob.sync(path.join(dir, '*', 'index.js')) || [];
|
||||
return files.map(function (file) {
|
||||
return file.replace(dir, 'plugins').replace(/\.js$/, '');
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = function (config) {
|
||||
var bundled_plugins = plugins(config.bundled_plugins_folder);
|
||||
var external_plugins = plugins(config.external_plugins_folder);
|
||||
return bundled_plugins.concat(external_plugins);
|
||||
};
|
||||
|
47
src/server/package.json
Normal file
47
src/server/package.json
Normal file
|
@ -0,0 +1,47 @@
|
|||
{
|
||||
"name": "kibana",
|
||||
"description": "Kibana is an open source (Apache Licensed), browser based analytics and search dashboard for Elasticsearch. Kibana is a snap to setup and start using. Kibana strives to be easy to get started with, while also being flexible and powerful, just like Elasticsearch.",
|
||||
"keywords": [
|
||||
"kibana",
|
||||
"elasticsearch",
|
||||
"logstash",
|
||||
"analytics",
|
||||
"visualizations",
|
||||
"dashboards",
|
||||
"dashboarding"
|
||||
],
|
||||
"homepage": "http://www.elasticsearch.org/overview/kibana/",
|
||||
"bugs": "https://github.com/elasticsearch/kibana/issues",
|
||||
"license": "Apache-2.0",
|
||||
"author": "Rashid Khan <rashid.khan@elasticsearch.com>",
|
||||
"contributors": [
|
||||
"Spencer Alger <spencer.alger@elasticsearch.com>",
|
||||
"Chris Cowan <chris.cowan@elasticsearch.com>",
|
||||
"Joe Fleming <joe.fleming@elasticsearch.com>",
|
||||
"Lukas Olson <lukas.olson@elasticsearch.com>"
|
||||
],
|
||||
"version": "4.0.0-rc1",
|
||||
"private": false,
|
||||
"scripts": {
|
||||
"start": "node ./bin/kibana.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/elasticsearch/kibana.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"body-parser": "~1.10.1",
|
||||
"compression": "^1.3.0",
|
||||
"cookie-parser": "~1.3.3",
|
||||
"debug": "~2.1.1",
|
||||
"express": "~4.10.6",
|
||||
"glob": "^4.3.2",
|
||||
"http-proxy": "^1.8.1",
|
||||
"jade": "~1.8.2",
|
||||
"js-yaml": "^3.2.5",
|
||||
"less-middleware": "1.0.x",
|
||||
"lodash": "^2.4.1",
|
||||
"morgan": "~1.5.1",
|
||||
"serve-favicon": "~2.2.0"
|
||||
}
|
||||
}
|
8
src/server/public/stylesheets/style.less
Normal file
8
src/server/public/stylesheets/style.less
Normal file
|
@ -0,0 +1,8 @@
|
|||
body {
|
||||
padding: 50px;
|
||||
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #00B7FF;
|
||||
}
|
18
src/server/routes/index.js
Normal file
18
src/server/routes/index.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
var express = require('express');
|
||||
var router = express.Router();
|
||||
var config = require('../config');
|
||||
var _ = require('lodash');
|
||||
|
||||
router.get('/config', function (req, res, next) {
|
||||
var excludedKeys = [
|
||||
'elasticsearch_url',
|
||||
'elasticsearch_username',
|
||||
'elasticsearch_password',
|
||||
'elasticsearch_preserve_host'
|
||||
];
|
||||
var data = _.omit(config.kibana, excludedKeys);
|
||||
data.plugins = config.plugins;
|
||||
res.json(data);
|
||||
});
|
||||
|
||||
module.exports = router;
|
51
src/server/routes/proxy.js
Normal file
51
src/server/routes/proxy.js
Normal file
|
@ -0,0 +1,51 @@
|
|||
var express = require('express');
|
||||
var router = module.exports = express.Router();
|
||||
var httpProxy = require('http-proxy');
|
||||
var config = require('../config');
|
||||
var url = require('url');
|
||||
var target = url.parse(config.elasticsearch);
|
||||
var proxy = new httpProxy.createProxyServer();
|
||||
var buffer = require('buffer');
|
||||
|
||||
proxy.on('proxyReq', function (proxyReq, req, res, options) {
|
||||
// To support the elasticsearch_preserve_host feature we need to change the
|
||||
// host header to the target host header.
|
||||
if (config.kibana.elasticsearch_preserve_host) {
|
||||
proxyReq.setHeader('host', target.host);
|
||||
}
|
||||
|
||||
// Support for handling basic auth
|
||||
if (config.kibana.elasticsearch_username && config.kibana.elasticsearch_password) {
|
||||
var code = new buffer.Buffer(config.kibana.elasticsearch_username + ':' + config.kibana.elasticsearch_password);
|
||||
var auth = 'Basic ' + code.toString('base64');
|
||||
proxyReq.setHeader('authorization', auth);
|
||||
}
|
||||
});
|
||||
|
||||
// Error handling for the proxy
|
||||
proxy.on('error', function (err, req, res) {
|
||||
console.log(err.code, err.message);
|
||||
var code = 502;
|
||||
var body = { message: 'Bad Gateway' };
|
||||
|
||||
if (err.message === 'ECONNREFUSED') {
|
||||
body.message = 'Unable to connect to Elasticsearch';
|
||||
}
|
||||
|
||||
if (err.message === 'DEPTH_ZERO_SELF_SIGNED_CERT') {
|
||||
body.message = 'SSL handshake with Elasticsearch failed';
|
||||
}
|
||||
|
||||
res.writeHead(502, { 'Content-Type': 'application/json' });
|
||||
res.end(JSON.stringify(body));
|
||||
});
|
||||
|
||||
router.use(function (req, res, next) {
|
||||
var options = {
|
||||
target: config.elasticsearch,
|
||||
secure: config.kibana.verify_ssl,
|
||||
xfwd: true
|
||||
};
|
||||
proxy.web(req, res, options);
|
||||
});
|
||||
|
6
src/server/views/error.jade
Normal file
6
src/server/views/error.jade
Normal file
|
@ -0,0 +1,6 @@
|
|||
extends layout
|
||||
|
||||
block content
|
||||
h1= message
|
||||
h2= error.status
|
||||
pre #{error.stack}
|
5
src/server/views/index.jade
Normal file
5
src/server/views/index.jade
Normal file
|
@ -0,0 +1,5 @@
|
|||
extends layout
|
||||
|
||||
block content
|
||||
h1= title
|
||||
p Welcome to #{title}
|
7
src/server/views/layout.jade
Normal file
7
src/server/views/layout.jade
Normal file
|
@ -0,0 +1,7 @@
|
|||
doctype html
|
||||
html
|
||||
head
|
||||
title= title
|
||||
link(rel='stylesheet', href='/stylesheets/style.css')
|
||||
body
|
||||
block content
|
Loading…
Add table
Add a link
Reference in a new issue