Skip to content

Commit

Permalink
Merge pull request #253 from sematext/geo-refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
Adnan Rahić authored Aug 21, 2020
2 parents 67954f0 + 6c0eaef commit 1828440
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 98 deletions.
9 changes: 8 additions & 1 deletion bin/logagent.js
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,14 @@ LaCli.prototype.loadPlugins = function (configFile) {
) {
outputFilter.push({
module: 'geoip',
fields: this.argv.geoIPFields || ['client_ip'],
fields: this.argv.geoipField || null,
debug: false
})
}
if (this.argv.geoipEnabled) {
outputFilter.push({
module: 'geoip',
fields: this.argv.geoipField || null,
debug: false
})
}
Expand Down
34 changes: 34 additions & 0 deletions config/examples/file-input-geoip-es-output.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Global options
options:
debug: true
# geoipEnabled: true
# geoipField: client_ip

input:
files:
- /var/log/nginx

parser:
patterns:
-
sourceName: !!js/regexp /.*/
match:
- type: web
regex: !!js/regexp ^([0-9a-f.:]+)\s[-|\S+]\s(.*)
fields:
- client_ip:string
- message:string

# outputFilter:
# geoip:
# module: geoip
# field: client_ip
# debug: true

output:
# stdout: yaml

elasticsearch:
module: elasticsearch
url: https://logsene-receiver.sematext.com
index: token
19 changes: 8 additions & 11 deletions lib/core/cliArgs.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,8 @@ module.exports = (function () {
'true/false to enable/disable geoip lookups, default field "client_ip"'
)
.option(
'--geoipFields <value>',
'comma separated list of fields for geoip lookups'
'--geoipField <value>',
'string field name for geoip lookup'
)
.option(
'--diskBufferDir <directory>',
Expand Down Expand Up @@ -254,22 +254,19 @@ module.exports = (function () {
}
// overwrite env var from CLI for logsene-js
process.LOGSENE_MAX_MESSAGE_FIELD_SIZE = argv.maxLogSize
if (process.env.GEOIP_ENABLED === 'true' && argv.geoipFields === undefined) {

if (process.env.GEOIP_ENABLED === 'true' && argv.geoipField === undefined) {
argv.geoipEnabled = true
}
if (argv.geoipEnabled === 'true' || argv.geoipEnabled === true) {
if (!process.env.GEOIP_ENABLED === 'true') {
process.env.GEOIP_ENABLED = 'true'
}
if (process.env.GEOIP_FIELDS && argv.geoipFields === undefined) {
argv.geoipFields = process.env.GEOIP_FIELDS
}
if (argv.geoipFields) {
argv.geoipFields = argv.geoipFields.replace(/\s/g, '').split(',')
process.env.GEOIP_FIELDS = argv.geoipFields
if (process.env.GEOIP_FIELD && argv.geoipField === undefined) {
argv.geoipField = process.env.GEOIP_FIELD
}
if (!process.env.MAXMIND_DB_DIR) {
process.env.MAXMIND_DB_DIR = '/tmp/'
if (argv.geoipField && process.env.GEOIP_FIELD === undefined) {
process.env.GEOIP_FIELD = argv.geoipField
}
}
if (argv.geoipEnabled === 'false' || argv.geoipEnabled === false) {
Expand Down
1 change: 1 addition & 0 deletions lib/core/configLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ function convertToCliArgs (cfg, argv) {
if (cfg.options) {
setProperty(flatCfg, argv, 'options.tailStartPosition', 'tailStartPosition')
setProperty(flatCfg, argv, 'options.geoipEnabled', 'geoipEnabled')
setProperty(flatCfg, argv, 'options.geoipField', 'geoipField')
setProperty(flatCfg, argv, 'options.suppress', 'suppress')
setProperty(flatCfg, argv, 'options.printStats', 'printStats')
setProperty(flatCfg, argv, 'options.maxLogSize', 'maxLogSize')
Expand Down
120 changes: 35 additions & 85 deletions lib/plugins/output-filter/geoip.js
Original file line number Diff line number Diff line change
@@ -1,105 +1,55 @@
var path = require('path')
var fs = require('fs')
var consoleLogger = require('../../util/logger.js')
var maxmindUpdate = require('../../parser/maxmind-update')
var MaxMindReader = require('maxmind').Reader
var cityLookup = null
var geoIpStatus = {
maxmindDbDir: process.env.MAXMIND_DB_DIR || '/tmp/',
const publicIp = require('public-ip')
const consoleLogger = require('../../util/logger.js')
const geoIpStatus = {
debug: !!process.env.DEBUG
}

function initMaxmind () {
maxmindUpdate(true, geoIpStatus.maxmindDbDir, function (err, fileName) {
if (geoIpStatus.debug) {
consoleLogger.debug('GeoIP: init GeoIP DB ' + fileName)
}
if (err) {
function initIpAddress () {
publicIp.v4()
.then(ip => {
consoleLogger.log('GeoIP: Loading Public IP')
geoIpStatus.ipAddress = ip
})
.catch(err => {
consoleLogger.error('GeoIP: error ' + err)
geoIpStatus.geoIpFailed = true
return
}
try {
fs.statSync(fileName)
cityLookup = new MaxMindReader(fs.readFileSync(fileName), {
watchForUpdates: true
})
if (cityLookup) {
consoleLogger.debug('GeoIP: open ' + fileName)
} else {
consoleLogger.log('GeoIP: error ' + err)
}
if (geoIpStatus.fields) {
consoleLogger.log(
'GeoIP: lookup enabled for fields ' + geoIpStatus.fields
)
} else {
consoleLogger.log('GeoIP: lookup enabled ')
}
} catch (fsStatError) {
geoIpStatus.geoIpFailed = true
consoleLogger.error('GeoIP: error ' + fsStatError)
}
})
})
}

function geoipLookup (parsedObject, fieldName, outputFieldName) {
if (cityLookup != null && parsedObject[fieldName]) {
var location = cityLookup.get(parsedObject[fieldName])
if (
location &&
location.country &&
location.city &&
location.city.names &&
location.city.names.en
) {
parsedObject[outputFieldName || 'geoip'] = {
location: [location.location.longitude, location.location.latitude],
info: {
country: location.country.iso_code,
continent: location.continent.code,
city: location.city.names.en
}
}
function geoipOutputFilter (context, config, eventEmitter, data, callback) {
geoIpStatus.debug = config.debug
geoIpStatus.field = process.env.GEOIP_FIELD || geoIpStatus.field || config.field

if (geoIpStatus.field) {
if (geoIpStatus.debug) {
consoleLogger.log('GeoIP: Lookup enabled for field: ' + geoIpStatus.field)
}
} else {
return null
}
}

function geoipOutputFilter (context, config, eventEmitter, data, callback) {
// get config values from output-filter config
if (!geoIpStatus.fields) {
if (process.env.GEOIP_FIELDS) {
geoIpStatus.fields = process.env.GEOIP_FIELDS.replace(/\s/g, '').split(
','
)
if (data[geoIpStatus.field]) {
data.geo = {
ip: data[geoIpStatus.field]
}
}
geoIpStatus.fields = geoIpStatus.fields || config.fields || ['client_ip']
geoIpStatus.debug = config.debug
consoleLogger.log('GeoIP: lookup enabled for fields ' + geoIpStatus.fields)
return callback(null, data)
}

if (geoIpStatus.geoIpFailed === true) {
if (geoIpStatus.debug) {
console.log('GeoIP: Lookup failed for the Public IP address')
}

return callback(null, data)
}
for (var i = 0; i < geoIpStatus.fields.length; i++) {
if (data[geoIpStatus.fields[i]] !== undefined) {
geoipLookup(data, geoIpStatus.fields[i], 'geoip')
}

if (geoIpStatus.debug) {
console.log(`GeoIP: The Public IP address is ${geoIpStatus.ipAddress}`)
}
data.geo = {
ip: geoIpStatus.ipAddress
}
return callback(null, data)
}

/*
function test () {
var cfg = { fields: ['client_ip'], maxmindDbDir: '/tmp/', debug: true }
setInterval(() => {
geoipOutputFilter(null, cfg, null, { client_ip: '94.216.99.1'}, console.log)
}, 200)
}
*/

consoleLogger.log('GeoIP: Loading Maxmind DB ')
initMaxmind()
initIpAddress()

module.exports = geoipOutputFilter
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@
"js-yaml": "^3.14.0",
"json-influx": "^0.3.0",
"kubernetes-client": "^8.3.7",
"logsene-js": "^1.1.71",
"logsene-js": "^1.1.72",
"lru-cache": "^5.1.1",
"maxmind": "^3.1.2",
"maxmind-geolite-mirror": "^1.1.3",
Expand All @@ -113,6 +113,7 @@
"mysql": "^2.16.0",
"pg": "^7.18.2",
"prettyjson": "^1.2.1",
"public-ip": "^4.0.2",
"query-string": "^6.12.1",
"requestretry": "^3.0.2",
"rotating-file-stream": "^1.3.9",
Expand Down

0 comments on commit 1828440

Please sign in to comment.