mirror of
https://github.com/Refactorio/RedMew.git
synced 2025-03-17 21:08:08 +02:00
Add error_logging
This commit is contained in:
parent
12557f8102
commit
2428a93154
@ -6,6 +6,7 @@ local Event = require 'utils.event'
|
||||
local Game = require 'utils.game'
|
||||
local Timestamp = require 'utils.timestamp'
|
||||
local Print = require('utils.print_override')
|
||||
local ErrorLogging = require 'utils.error_logging'
|
||||
|
||||
local serialize = serpent.serialize
|
||||
local concat = table.concat
|
||||
@ -18,11 +19,13 @@ local serialize_options = {sparse = true, compact = true}
|
||||
local Public = {}
|
||||
|
||||
local server_time = {secs = nil, tick = 0}
|
||||
ErrorLogging.server_time = server_time
|
||||
|
||||
Global.register(
|
||||
server_time,
|
||||
function(tbl)
|
||||
server_time = tbl
|
||||
ErrorLogging.server_time = tbl
|
||||
end
|
||||
)
|
||||
|
||||
@ -299,6 +302,7 @@ local function data_set_changed(data)
|
||||
local success, err = pcall(handler, data)
|
||||
if not success then
|
||||
log(err)
|
||||
ErrorLogging.generate_error_report(err)
|
||||
error(err, 2)
|
||||
end
|
||||
end
|
||||
@ -307,6 +311,7 @@ local function data_set_changed(data)
|
||||
local success, err = pcall(handler, data)
|
||||
if not success then
|
||||
log(err)
|
||||
ErrorLogging.generate_error_report(err)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -2,6 +2,7 @@ local Event = require 'utils.event'
|
||||
local Game = require 'utils.game'
|
||||
local Utils = require 'utils.core'
|
||||
local Timestamp = require 'utils.timestamp'
|
||||
local ErrorLogging = require 'utils.error_logging'
|
||||
local Rank = require 'features.rank_system'
|
||||
local Donator = require 'features.donator'
|
||||
local Server = require 'features.server'
|
||||
@ -247,11 +248,14 @@ function Command.add(command_name, options, callback)
|
||||
if _DEBUG then
|
||||
print(format("%s triggered an error running a command and has been logged: '%s' with arguments %s", player_name, command_name, serialized_arguments))
|
||||
print(error)
|
||||
ErrorLogging.generate_error_report(error)
|
||||
return
|
||||
end
|
||||
|
||||
print(format('There was an error running %s, it has been logged.', command_name))
|
||||
log(format("Error while running '%s' with arguments %s: %s", command_name, serialized_arguments, error))
|
||||
local err = format("Error while running '%s' with arguments %s: %s", command_name, serialized_arguments, error)
|
||||
log(err)
|
||||
ErrorLogging.generate_error_report(err)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
86
utils/error_logging.lua
Normal file
86
utils/error_logging.lua
Normal file
@ -0,0 +1,86 @@
|
||||
--[[
|
||||
This module creates a file of just trapped lua errors. It is possible that this module misses errors, therefore it is advised
|
||||
that users also verify their server/game logs.
|
||||
]]
|
||||
-- Dependencies
|
||||
local Timestamp = require 'utils.timestamp'
|
||||
|
||||
-- Localized functions
|
||||
local floor = math.floor
|
||||
local format = string.format
|
||||
local insert = table.insert
|
||||
local concat = table.concat
|
||||
|
||||
-- Local constants
|
||||
local minutes_to_ticks = 60 * 60
|
||||
local hours_to_ticks = 60 * 60 * 60
|
||||
local ticks_to_minutes = 1 / minutes_to_ticks
|
||||
local ticks_to_hours = 1 / hours_to_ticks
|
||||
local warning = '\n\n\n\nTHIS LOG IS NOT ALL-INCLUSIVE AND CAN MISS ERRORS. IF THERE ARE ANY SUSPICIONS OF ERRORS CHECK THE LOGS.\n\n\n\n'
|
||||
|
||||
-- Local vars
|
||||
local Public = {
|
||||
server_time = {secs = nil, tick = 0}
|
||||
}
|
||||
local first_error = true
|
||||
|
||||
--- Copied from utils.core, turns ticks into a human-readable time.
|
||||
local function format_time(ticks)
|
||||
local result = {}
|
||||
|
||||
local hours = floor(ticks * ticks_to_hours)
|
||||
if hours > 0 then
|
||||
ticks = ticks - hours * hours_to_ticks
|
||||
insert(result, hours)
|
||||
if hours == 1 then
|
||||
insert(result, 'hour')
|
||||
else
|
||||
insert(result, 'hours')
|
||||
end
|
||||
end
|
||||
|
||||
local minutes = floor(ticks * ticks_to_minutes)
|
||||
insert(result, minutes)
|
||||
if minutes == 1 then
|
||||
insert(result, 'minute')
|
||||
else
|
||||
insert(result, 'minutes')
|
||||
end
|
||||
|
||||
return concat(result, ' ')
|
||||
end
|
||||
|
||||
--- Takes the given string and generates an entry in the error file.
|
||||
function Public.generate_error_report(str)
|
||||
Debug.print()
|
||||
local server_time = Public.server_time.secs
|
||||
|
||||
local server_time_str = '(Server time: unavailable)'
|
||||
local file_name = 'redmew_errors.log'
|
||||
if server_time then
|
||||
server_time_str = format('(Server time: %s)', Timestamp.to_string(server_time))
|
||||
file_name = Timestamp.to_date_string(server_time) .. '_' .. file_name
|
||||
else
|
||||
game.write_file(file_name, '', false, 0)
|
||||
end
|
||||
|
||||
if first_error then
|
||||
server_time_str = warning .. server_time_str
|
||||
first_error = nil
|
||||
end
|
||||
|
||||
local tick = 'pre-game'
|
||||
if game then
|
||||
tick = format_time(game.tick)
|
||||
end
|
||||
tick = 'Time of error: ' .. tick
|
||||
|
||||
local redmew_version = global.redmew_version or 'Unknown'
|
||||
redmew_version = 'RedMew version: ' .. redmew_version
|
||||
|
||||
local output = concat({server_time_str, tick, redmew_version, str, '\n'}, '\n')
|
||||
|
||||
game.write_file(file_name, output, true, 0)
|
||||
end
|
||||
|
||||
return Public
|
@ -1,5 +1,6 @@
|
||||
-- This module exists to break the circular dependency between event.lua and global.lua.
|
||||
-- It is not expected that any user code would require this module instead event.lua should be required.
|
||||
local ErrorLogging = require 'utils.error_logging'
|
||||
|
||||
local Public = {}
|
||||
|
||||
@ -16,18 +17,22 @@ local log = log
|
||||
local script_on_event = script.on_event
|
||||
local script_on_nth_tick = script.on_nth_tick
|
||||
|
||||
local function call_handlers(handlers, event)
|
||||
if _DEBUG then
|
||||
local call_handlers
|
||||
if _DEBUG then
|
||||
function call_handlers(handlers, event)
|
||||
for i = 1, #handlers do
|
||||
local handler = handlers[i]
|
||||
handler(event)
|
||||
end
|
||||
else
|
||||
end
|
||||
else
|
||||
function call_handlers(handlers, event)
|
||||
for i = 1, #handlers do
|
||||
local handler = handlers[i]
|
||||
local success, error = pcall(handler, event)
|
||||
if not success then
|
||||
log(error)
|
||||
ErrorLogging.generate_error_report(error)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -8,6 +8,7 @@ local Queue = require 'utils.queue'
|
||||
local PriorityQueue = require 'utils.priority_queue'
|
||||
local Event = require 'utils.event'
|
||||
local Token = require 'utils.token'
|
||||
local ErrorLogging = require 'utils.error_logging'
|
||||
|
||||
local Task = {}
|
||||
|
||||
@ -45,6 +46,7 @@ local function on_tick()
|
||||
error(result)
|
||||
else
|
||||
log(result)
|
||||
ErrorLogging.generate_error_report(result)
|
||||
end
|
||||
Queue.pop(queue)
|
||||
global.total_task_weight = global.total_task_weight - task.weight
|
||||
@ -64,6 +66,7 @@ local function on_tick()
|
||||
error(result)
|
||||
else
|
||||
log(result)
|
||||
ErrorLogging.generate_error_report(result)
|
||||
end
|
||||
end
|
||||
PriorityQueue.pop(callbacks, comp)
|
||||
|
@ -119,15 +119,15 @@ local function normalise(year, month, day, hour, min, sec)
|
||||
end
|
||||
|
||||
--- Converts unix epoch timestamp into table {year: number, month: number, day: number, hour: number, min: number, sec: number}
|
||||
-- @param sec<number> unix epoch timestamp
|
||||
-- @return {year: number, month: number, day: number, hour: number, min: number, sec: number}
|
||||
-- @param <number> sec unix epoch timestamp
|
||||
-- @return <table> {year: number, month: number, day: number, hour: number, min: number, sec: number}
|
||||
function Public.to_timetable(secs)
|
||||
return normalise(1970, 1, 1, 0, 0, secs)
|
||||
end
|
||||
|
||||
--- Converts timetable into unix epoch timestamp
|
||||
-- @param timetable<table> {year: number, month: number, day: number, hour: number, min: number, sec: number}
|
||||
-- @return number
|
||||
-- @param <table> timetable {year: number, month: number, day: number, hour: number, min: number, sec: number}
|
||||
-- @return <number>
|
||||
function Public.from_timetable(timetable)
|
||||
local tt = normalise(timetable.year, timetable.month, timetable.day, timetable.hour, timetable.min, timetable.sec)
|
||||
|
||||
@ -142,11 +142,19 @@ function Public.from_timetable(timetable)
|
||||
end
|
||||
|
||||
--- Converts unix epoch timestamp into human readable string.
|
||||
-- @param secs<type> unix epoch timestamp
|
||||
-- @return string
|
||||
-- @param <number> secs unix epoch timestamp
|
||||
-- @return <string>
|
||||
function Public.to_string(secs)
|
||||
local tt = normalise(1970, 1, 1, 0, 0, secs)
|
||||
return strformat('%04u-%02u-%02u %02u:%02u:%02d', tt.year, tt.month, tt.day, tt.hour, tt.min, tt.sec)
|
||||
end
|
||||
|
||||
--- Converts unix epoch timestamp into a date string.
|
||||
-- @param <number> secs unix epoch timestamp
|
||||
-- @return <string> With data in format YYYY-MM-DD
|
||||
function Public.to_date_string(secs)
|
||||
local tt = normalise(1970, 1, 1, 0, 0, secs)
|
||||
return strformat('%04u-%02u-%02u', tt.year, tt.month, tt.day)
|
||||
end
|
||||
|
||||
return Public
|
||||
|
Loading…
x
Reference in New Issue
Block a user