|
|
|
@@ -1,3 +1,4 @@
|
|
|
|
|
require "log"
|
|
|
|
|
require "file_utils"
|
|
|
|
|
require "json"
|
|
|
|
|
require "socket"
|
|
|
|
@@ -5,11 +6,14 @@ require "sqlite3"
|
|
|
|
|
require "pg"
|
|
|
|
|
require "option_parser"
|
|
|
|
|
require "uuid"
|
|
|
|
|
require "system"
|
|
|
|
|
require "./models/access_log"
|
|
|
|
|
require "./models/crawler"
|
|
|
|
|
require "./swd"
|
|
|
|
|
|
|
|
|
|
VERSION = "0.5.1"
|
|
|
|
|
VERSION = "0.5.5"
|
|
|
|
|
|
|
|
|
|
Log.setup_from_env
|
|
|
|
|
|
|
|
|
|
# Default socket location
|
|
|
|
|
socket = "/tmp/access_log.socket"
|
|
|
|
@@ -21,7 +25,7 @@ crawler = false
|
|
|
|
|
crawlers = [] of Crawler
|
|
|
|
|
# Fields in database
|
|
|
|
|
# TODO: Obtain them from AccessLog
|
|
|
|
|
fields = %w[id remote_user host msec server_protocol request_method request_completion uri request_uri query_string status sent_http_content_type sent_http_content_encoding sent_http_etag sent_http_last_modified http_accept http_accept_encoding http_accept_language http_pragma http_cache_control http_if_none_match http_dnt http_user_agent http_origin http_referer request_time bytes_sent body_bytes_sent request_length http_connection pipe connection_requests geoip2_data_country_name geoip2_data_city_name ssl_server_name ssl_protocol ssl_early_data ssl_session_reused ssl_curves ssl_ciphers ssl_cipher sent_http_x_xss_protection sent_http_x_frame_options sent_http_x_content_type_options sent_http_strict_transport_security nginx_version pid crawler datacenter_co2 network_co2 consumer_device_co2 production_co2 total_co2]
|
|
|
|
|
fields = %w[id remote_user host msec server_protocol request_method request_completion uri request_uri query_string status sent_http_content_type sent_http_content_encoding sent_http_etag sent_http_last_modified http_accept http_accept_encoding http_accept_language http_pragma http_cache_control http_if_none_match http_dnt http_user_agent http_origin http_referer request_time bytes_sent body_bytes_sent request_length http_connection pipe connection_requests geoip2_data_country_name geoip2_data_city_name ssl_server_name ssl_protocol ssl_early_data ssl_session_reused ssl_curves ssl_ciphers ssl_cipher sent_http_x_xss_protection sent_http_x_frame_options sent_http_x_content_type_options sent_http_strict_transport_security nginx_version pid crawler datacenter_co2 network_co2 consumer_device_co2 production_co2 total_co2 node]
|
|
|
|
|
# Params for the query
|
|
|
|
|
params = [] of String
|
|
|
|
|
# SWD
|
|
|
|
@@ -31,6 +35,7 @@ datacenter : String? = nil
|
|
|
|
|
renewable = false
|
|
|
|
|
device_country = false
|
|
|
|
|
intensity = :marginal
|
|
|
|
|
node = false
|
|
|
|
|
|
|
|
|
|
# Parse CLI flags
|
|
|
|
|
OptionParser.parse do |p|
|
|
|
|
@@ -79,10 +84,14 @@ OptionParser.parse do |p|
|
|
|
|
|
p.on "-A", "--average-intensity", "Use average intensity figures rather than marginal" do
|
|
|
|
|
intensity = :average
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
p.on "-n", "--node", "Send node hostname" do
|
|
|
|
|
node = true
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# Parameterize values according to database URI
|
|
|
|
|
if database.starts_with? "postgresql://"
|
|
|
|
|
if database.starts_with?("postgresql://") || database.starts_with?("postgres://")
|
|
|
|
|
params = fields.map_with_index do |_, i|
|
|
|
|
|
"$#{i + 1}"
|
|
|
|
|
end
|
|
|
|
@@ -121,7 +130,8 @@ db = DB.open database do |db|
|
|
|
|
|
while true
|
|
|
|
|
begin
|
|
|
|
|
msg, _ = server.receive(1024 * 64) # 64K
|
|
|
|
|
_, _, _, _, json = msg.split(" ", 5)
|
|
|
|
|
_, json = msg.split("{", 2)
|
|
|
|
|
json = "{#{json}"
|
|
|
|
|
|
|
|
|
|
# Parse input
|
|
|
|
|
access_log = AccessLog.from_json(json || "{}")
|
|
|
|
@@ -184,10 +194,12 @@ db = DB.open database do |db|
|
|
|
|
|
(swd ? s.try(&.network_co2) : nil),
|
|
|
|
|
(swd ? s.try(&.consumer_device_co2) : nil),
|
|
|
|
|
(swd ? s.try(&.production_co2) : nil),
|
|
|
|
|
(swd ? s.try(&.total_co2) : nil)
|
|
|
|
|
(swd ? s.try(&.total_co2) : nil),
|
|
|
|
|
(node ? System.hostname : nil)
|
|
|
|
|
|
|
|
|
|
# Ignore parsing errors
|
|
|
|
|
rescue JSON::ParseException
|
|
|
|
|
rescue e : JSON::ParseException
|
|
|
|
|
Log.warn &.emit("Parse exception", error: e.message)
|
|
|
|
|
rescue IO::Error
|
|
|
|
|
server.close
|
|
|
|
|
FileUtils.rm(socket) if File.exists? socket
|
|
|
|
|