The Logger component provides a centralized logging system with multiple output targets: console, files, database, and Discord webhooks. It supports different log levels for filtering and categorizing log messages.
Log Levels
The Logger supports 6 log levels with increasing severity:
Level Method Use Case Console Color 0 Log Legacy/general Default 1 Trace Detailed debugging Default 2 Info General information Blue 3 Warn Warnings Yellow 4 Error Errors Red 5 Critical Critical failures Bright Red
Method Signature
Important: All logger methods use this signature (not the commonly assumed signature):Logger : MethodName ( component , log , flags , data )
Parameters:
Name Type Required Description component string Yes Component/resource name log string Yes Log message flags table No Output flags {console, file, discord, database} data any No Additional data to store (database only)
Logging Methods
Info
Log informational message.
Example:
-- Server side
Logger : Info ( 'MyResource' , 'Player joined server' )
-- With flags
Logger : Info ( 'MyResource' , 'Important event occurred' , {
console = true ,
file = true ,
discord = true
})
-- With data
Logger : Info ( 'MyResource' , 'Transaction completed' , {
console = true ,
database = true
}, {
amount = 5000 ,
from = 'player1' ,
to = 'player2'
})
Warn
Log warning message.
Example:
-- Server side
Logger : Warn ( 'AntiCheat' , 'Suspicious activity detected' , {
console = true ,
discord = true
})
Error
Log error message.
Example:
-- Server side
Logger : Error ( 'Database' , 'Failed to save player data' , {
console = true ,
file = true ,
discord = true
}, {
playerId = 123 ,
error = errorMessage
})
Critical
Log critical failure.
Example:
-- Server side
Logger : Critical ( 'Core' , 'System failure detected' , {
console = true ,
file = true ,
discord = {
embed = true ,
type = 'error' ,
content = '@everyone Critical system failure!'
}
}, {
system = 'database' ,
uptime = os.time ()
})
Trace
Log detailed debugging information.
Example:
-- Server side
Logger : Trace ( 'Inventory' , 'Item added to inventory' , {
console = true
}, {
item = 'water' ,
count = 5 ,
slot = 3
})
Log (Legacy)
General logging (retained for backward compatibility).
Example:
-- Server side
Logger : Log ( 'MyResource' , 'Generic log message' )
Log() method is legacy. Use Info(), Warn(), Error(), etc. instead for proper log level categorization.
Output Flags
The flags parameter controls where logs are output:
Console Output
flags = {
console = true -- Print to server console
}
Console Format:
[INFO] [MyResource] Player joined server
[WARN] [AntiCheat] Suspicious activity
[ERROR] [Database] Connection failed
Log Level Filter:
Controlled by Convar.LOGGING.value
Only logs >= this level will print to console
Configured in server.cfg
File Output
flags = {
file = true -- Write to log file
}
File Structure:
logs/
├── MyResource/
│ ├── 2025-01-15.log
│ └── 2025-01-16.log
├── Database/
│ └── 2025-01-15.log
└── AntiCheat/
└── 2025-01-15.log
File Format:
[INFO] [02:30:45 PM] Player joined server
[WARN] [02:31:12 PM] Suspicious activity detected
[ERROR] [02:32:00 PM] Connection failed
Files are organized by component name and date. New file created daily.
Discord Output
Discord logging only fires when GlobalState.IsProduction is true AND the log level meets the minimum threshold (Convar.LOGGING.value). It will not send webhooks in development mode.
-- Simple Discord webhook
flags = {
discord = true
}
-- Advanced Discord embed
flags = {
discord = {
embed = true ,
type = 'info' , -- or 'success', 'warning', 'error', 'critical'
title = 'System Alert' ,
description = 'Optional description' ,
content = 'Message content' ,
webhook = 'https://discord.com/api/webhooks/...' -- Optional override webhook
}
}
Discord Webhook Configuration:
Set in server.cfg:
set discord_log_webhook "https://discord.com/api/webhooks/YOUR_WEBHOOK_ID/YOUR_WEBHOOK_TOKEN"
Embed Colors:
trace - Gray
info - Blue
success - Green
warning - Yellow
error - Red
critical - Bright Red
Example:
Logger : Info ( 'AntiCheat' , 'Player banned' , {
console = true ,
discord = {
embed = true ,
type = 'warning' ,
title = 'Player Banned' ,
description = 'Automatic ban for cheating' ,
content = '@here Cheater detected'
}
}, {
player = 'PlayerName' ,
reason = 'Aimbot detected' ,
evidence = 'Screenshot URL'
})
Database Output
flags = {
database = true
}
Database Storage:
Collection: logs
Only in production environment
Must pass data parameter for context
Document Structure:
{
date = 1705334400 , -- Unix timestamp
level = 2 , -- Log level (1-5)
component = 'MyResource' ,
log = 'Transaction completed' ,
data = { -- Your custom data
amount = 5000 ,
from = 'player1' ,
to = 'player2'
}
}
Database logging only works when all of these conditions are met:
Proxy.DatabaseReady is true (database connection established)
GlobalState.IsProduction is true (environment set to "prod")
flags.database = true is set in the flags parameter
Complete Examples
Basic Logging
-- Simple info log to console
Logger : Info ( 'MyResource' , 'Server started' )
-- Warning with file logging
Logger : Warn ( 'Security' , 'Failed login attempt' , {
console = true ,
file = true
})
-- Error with all outputs
Logger : Error ( 'Database' , 'Connection lost' , {
console = true ,
file = true ,
discord = true ,
database = true
}, {
host = 'localhost' ,
port = 27017 ,
error = errorMessage
})
Player Action Logging
-- Log player purchase
AddEventHandler ( 'shop:server:Purchase' , function ( itemName , price )
local src = source
local player = Fetch : Source ( src )
local char = player : GetData ( 'Character' )
Logger : Info ( 'Shop' , string.format (
'%s %s purchased %s for $%d' ,
char : GetData ( 'First' ),
char : GetData ( 'Last' ),
itemName ,
price
), {
console = true ,
file = true ,
database = true
}, {
characterSID = char : GetData ( 'SID' ),
accountID = player : GetData ( 'AccountID' ),
item = itemName ,
price = price ,
timestamp = os.time ()
})
end )
Anti-Cheat Detection
-- Detect and log cheating
AddEventHandler ( 'anticheat:detection' , function ( source , cheatType , details )
local player = Fetch : Source ( source )
local char = player : GetData ( 'Character' )
Logger : Critical ( 'AntiCheat' , string.format (
'CHEAT DETECTED: %s by %s %s (SID: %d)' ,
cheatType ,
char : GetData ( 'First' ),
char : GetData ( 'Last' ),
char : GetData ( 'SID' )
), {
console = true ,
file = true ,
discord = {
embed = true ,
type = 'critical' ,
title = '🚨 Cheat Detection' ,
content = '@here Immediate action required' ,
description = string.format ( '**Type:** %s \n **Player:** %s %s \n **Details:** %s' ,
cheatType ,
char : GetData ( 'First' ),
char : GetData ( 'Last' ),
details
)
},
database = true
}, {
characterSID = char : GetData ( 'SID' ),
accountID = player : GetData ( 'AccountID' ),
cheatType = cheatType ,
details = details ,
playerCoords = GetEntityCoords ( GetPlayerPed ( source ))
})
-- Ban player
DropPlayer ( source , 'Banned for cheating: ' .. cheatType )
end )
Best Practices
Choose Appropriate Log Levels
Use the right level for the right situation: -- ✅ Good
Logger : Info ( 'Shop' , 'Purchase completed' )
Logger : Warn ( 'Security' , 'Multiple failed login attempts' )
Logger : Error ( 'Database' , 'Connection failed' )
Logger : Critical ( 'Core' , 'System shutdown imminent' )
-- ❌ Bad
Logger : Error ( 'Shop' , 'Purchase completed' ) -- Not an error
Logger : Info ( 'Core' , 'Database exploded' ) -- Too severe for Info
Always pass data parameter for important logs: -- ✅ Good - includes context
Logger : Error ( 'Inventory' , 'Failed to add item' , {
console = true ,
database = true
}, {
characterSID = char : GetData ( 'SID' ),
item = itemName ,
count = count ,
error = errorMessage
})
-- ❌ Bad - no context
Logger : Error ( 'Inventory' , 'Failed to add item' )
Use file logging for high-frequency logs: -- ✅ Good - file only for frequent logs
Logger : Trace ( 'Movement' , 'Player moved' , {
console = false ,
file = true
})
-- ❌ Bad - console spam
Logger : Info ( 'Movement' , 'Player moved' , {
console = true
})
Next Steps
Core - Fetch Player and character data access
Core - Database Database operations
Configuration Server configuration
Middleware Event middleware system
Pro Tip: Create helper functions for common logging patterns:function LogPlayerAction ( component , action , char , data )
Logger : Info ( component , string.format (
'%s %s: %s' ,
char : GetData ( 'First' ),
char : GetData ( 'Last' ),
action
), {
console = true ,
file = true ,
database = true
}, data )
end