Health check endpoint
This commit is contained in:
@@ -1,9 +1,12 @@
|
||||
1.21.1 -- 2014-mm-dd
|
||||
1.22.0 -- 2014-mm-dd
|
||||
--------------------
|
||||
|
||||
Announcements:
|
||||
- Upgrades windshaft to 0.32.0
|
||||
|
||||
New features:
|
||||
- Health check endpoint
|
||||
|
||||
|
||||
1.21.0 -- 2014-10-24
|
||||
--------------------
|
||||
|
||||
@@ -5,6 +5,7 @@ var _ = require('underscore')
|
||||
, TemplateMaps = require('./template_maps.js')
|
||||
, Cache = require('./cache_validator')
|
||||
, os = require('os')
|
||||
, HealthCheck = require('./monitoring/health_check')
|
||||
;
|
||||
|
||||
if ( ! process.env['PGAPPNAME'] )
|
||||
@@ -665,6 +666,31 @@ var CartodbWindshaft = function(serverOptions) {
|
||||
|
||||
// ---- Template maps interface ends @}
|
||||
|
||||
var healthCheck = new HealthCheck(cartoData, serverOptions.queryTablesApi, Windshaft.tilelive);
|
||||
ws.get('/health', function(req, res) {
|
||||
var healthConfig = global.environment.health || {};
|
||||
|
||||
if (!!healthConfig.enabled) {
|
||||
var startTime = Date.now();
|
||||
healthCheck.check(healthConfig, function(err, result) {
|
||||
var ok = !err;
|
||||
var response = {
|
||||
enabled: true,
|
||||
ok: ok,
|
||||
elapsed: Date.now() - startTime,
|
||||
result: result
|
||||
};
|
||||
if (err) {
|
||||
response.err = err.message;
|
||||
}
|
||||
res.send(response, ok ? 200 : 503);
|
||||
|
||||
});
|
||||
} else {
|
||||
res.send({enabled: false, ok: true}, 200);
|
||||
}
|
||||
});
|
||||
|
||||
return ws;
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
var _ = require('underscore'),
|
||||
dot = require('dot'),
|
||||
fs = require('fs'),
|
||||
path = require('path'),
|
||||
Step = require('step');
|
||||
|
||||
function HealthCheck(metadataBackend, queryTablesApi, tilelive) {
|
||||
this.metadataBackend = metadataBackend;
|
||||
this.queryTablesApi = queryTablesApi;
|
||||
this.tilelive = tilelive;
|
||||
}
|
||||
|
||||
module.exports = HealthCheck;
|
||||
|
||||
|
||||
var mapnikOptions = {
|
||||
query: {
|
||||
metatile: 1,
|
||||
poolSize: 4,
|
||||
bufferSize: 64
|
||||
},
|
||||
protocol: 'mapnik:',
|
||||
slashes: true,
|
||||
xml: null
|
||||
};
|
||||
|
||||
var xmlTemplate = dot.template(fs.readFileSync(path.resolve(__dirname, 'map-config.xml'), 'utf-8'));
|
||||
|
||||
HealthCheck.prototype.check = function(config, callback) {
|
||||
|
||||
var self = this,
|
||||
startTime,
|
||||
result = {
|
||||
redis: {
|
||||
ok: false
|
||||
},
|
||||
postgresql: {
|
||||
ok: false
|
||||
},
|
||||
mapnik: {
|
||||
ok: false
|
||||
},
|
||||
tile: {
|
||||
ok: false
|
||||
}
|
||||
},
|
||||
mapnikXmlParams = _.extend({
|
||||
dbport: global.environment.postgres.port
|
||||
}, config);
|
||||
|
||||
Step(
|
||||
function getDBParams() {
|
||||
startTime = Date.now();
|
||||
self.metadataBackend.getAllUserDBParams(config.username, this);
|
||||
},
|
||||
function runQuery(err, dbParams) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
result.redis = {
|
||||
ok: !err,
|
||||
elapsed: Date.now() - startTime,
|
||||
size: Object.keys(dbParams).length
|
||||
};
|
||||
|
||||
dbParams.dbuser = _.template(global.environment.postgres_auth_user, {user_id: dbParams.dbuser});
|
||||
|
||||
mapnikXmlParams = _.extend(mapnikXmlParams, dbParams);
|
||||
|
||||
startTime = Date.now();
|
||||
self.queryTablesApi.getAffectedTablesInQuery(config.username, {
|
||||
user: dbParams.dbuser,
|
||||
pass: dbParams.dbpass,
|
||||
host: dbParams.dbhost,
|
||||
port: global.environment.postgres.port,
|
||||
dbname: dbParams.dbname,
|
||||
api_key: dbParams.apikey
|
||||
}, config.query, this);
|
||||
},
|
||||
function handleAffectedTablesQuery(err, affectedTables) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
result.postgresql = {
|
||||
ok: !err,
|
||||
elapsed: Date.now() - startTime,
|
||||
size: affectedTables.length
|
||||
};
|
||||
|
||||
this();
|
||||
},
|
||||
function loadMapnik(err) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
mapnikOptions.xml = xmlTemplate(mapnikXmlParams);
|
||||
|
||||
console.log(mapnikOptions.xml);
|
||||
startTime = Date.now();
|
||||
self.tilelive.load(mapnikOptions, this);
|
||||
},
|
||||
function getTile(err, source) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
result.mapnik = {
|
||||
ok: !err,
|
||||
elapsed: Date.now() - startTime
|
||||
};
|
||||
|
||||
startTime = Date.now();
|
||||
source.getTile(config.z, config.x, config.y, this);
|
||||
},
|
||||
function handleTile(err, tile) {
|
||||
result.tile = {
|
||||
ok: !err
|
||||
};
|
||||
|
||||
if (tile) {
|
||||
result.tile.elapsed = Date.now() - startTime;
|
||||
result.tile.size = tile.length;
|
||||
}
|
||||
|
||||
callback(err, result);
|
||||
}
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE Map[]>
|
||||
<Map srs="+init=epsg:3857" buffer-size="128" maximum-extent="-20037508.34,-20037508.34,20037508.34,20037508.34">
|
||||
|
||||
<Parameters>
|
||||
<Parameter name="format">png8:m=h</Parameter>
|
||||
<Parameter name="interactivity_layer">layer0</Parameter>
|
||||
<Parameter name="interactivity_fields">interactivity_id</Parameter>
|
||||
</Parameters>
|
||||
|
||||
|
||||
<Style name="layer0-labels" filter-mode="first">
|
||||
<Rule>
|
||||
<TextSymbolizer face-name="DejaVu Sans Book" size="18" label-position-tolerance="10" fill="#000000" halo-fill="#ffffff" halo-radius="1" dy="-10" allow-overlap="true" placement="point" placement-type="simple" ><![CDATA[[label]]]></TextSymbolizer>
|
||||
</Rule>
|
||||
</Style>
|
||||
<Style name="layer0" filter-mode="first">
|
||||
<Rule>
|
||||
<MarkersSymbolizer fill-opacity="0.9" stroke="#ffffff" stroke-width="2" stroke-opacity="1" placement="point" marker-type="ellipse" width="16" fill="#cc3333" allow-overlap="true" />
|
||||
</Rule>
|
||||
</Style>
|
||||
<Layer name="layer0"
|
||||
srs="+init=epsg:{{=it.srid}}">
|
||||
<StyleName>layer0</StyleName>
|
||||
<StyleName>layer0-labels</StyleName>
|
||||
<Datasource>
|
||||
<Parameter name="type"><![CDATA[postgis]]></Parameter>
|
||||
<Parameter name="user"><![CDATA[{{=it.dbuser}}]]></Parameter>
|
||||
<Parameter name="password"><![CDATA[]]></Parameter>
|
||||
<Parameter name="host"><![CDATA[{{=it.dbhost}}]]></Parameter>
|
||||
<Parameter name="port"><![CDATA[{{=it.dbport}}]]></Parameter>
|
||||
<Parameter name="dbname"><![CDATA[{{=it.dbname}}]]></Parameter>
|
||||
<Parameter name="extent"><![CDATA[-20037508.3,-20037508.3,20037508.3,20037508.3]]></Parameter>
|
||||
<Parameter name="row_limit"><![CDATA[0]]></Parameter>
|
||||
<Parameter name="simplify_geometries"><![CDATA[true]]></Parameter>
|
||||
<Parameter name="persist_connection"><![CDATA[false]]></Parameter>
|
||||
<Parameter name="asynchronous_request"><![CDATA[false]]></Parameter>
|
||||
<Parameter name="max_size"><![CDATA[500]]></Parameter>
|
||||
<Parameter name="geometry_field"><![CDATA[{{=it.geometry_field}}]]></Parameter>
|
||||
<Parameter name="srid"><![CDATA[{{=it.srid}}]]></Parameter>
|
||||
<Parameter name="table"><![CDATA[({{=it.query}}) as cdbq]]></Parameter>
|
||||
</Datasource>
|
||||
</Layer>
|
||||
|
||||
</Map>
|
||||
@@ -71,7 +71,8 @@ module.exports = function(redisPool) {
|
||||
varnish_secret: global.environment.varnish.secret,
|
||||
cache_enabled: global.environment.cache_enabled,
|
||||
log_format: global.environment.log_format,
|
||||
useProfiler: global.environment.useProfiler
|
||||
useProfiler: global.environment.useProfiler,
|
||||
queryTablesApi: queryTablesApi
|
||||
};
|
||||
|
||||
// Do not send unwatch on release
|
||||
|
||||
Generated
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "windshaft-cartodb",
|
||||
"version": "1.21.1",
|
||||
"version": "1.22.0",
|
||||
"dependencies": {
|
||||
"cartodb-psql": {
|
||||
"version": "0.4.0",
|
||||
@@ -1528,7 +1528,7 @@
|
||||
},
|
||||
"sphericalmercator": {
|
||||
"version": "1.0.2",
|
||||
"from": "sphericalmercator@~1.0.2"
|
||||
"from": "sphericalmercator@~1.0.1"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "windshaft-cartodb",
|
||||
"version": "1.21.1",
|
||||
"version": "1.22.0",
|
||||
"description": "A map tile server for CartoDB",
|
||||
"keywords": [
|
||||
"cartodb"
|
||||
|
||||
Reference in New Issue
Block a user