Zum Inhalt

CV.Log Module

Overview

The cv.log module is a comprehensive server-side logging system for the CasualV FiveM roleplay framework. It provides unified logging to console, Discord webhooks, and the database, enabling centralized monitoring and auditing of all server events.

Features

  • Multi-Channel Logging: Route logs to different Discord channels based on event type
  • Database Persistence: All logs are saved to the system_logs table for long-term storage and querying
  • Discord Integration: Real-time notifications via Discord embeds with color-coded event types
  • Player Context: Track logs with character and user information for better accountability
  • Type Classification: 10 different log types with unique colors and Discord icons
  • Metadata Storage: JSON-based metadata storage for complex log data

Log Types

Each log type has a unique color and Discord emoji icon for easy visual identification:

Type Color Icon Use Case
info Blue (#3447003) :information_source: General information
success Green (#65280) :white_check_mark: Successful operations
warning Yellow (#16776960) :warning: Warning messages
error Red (#16711680) :x: Error messages
admin Orange (#16753920) :shield: Admin actions
player Light Blue (#9936031) :bust_in_silhouette: Player events
server Gray (#8359053) :gear: Server operations
security Purple (#10181046) :lock: Security events
economy Gold (#15844367) :moneybag: Transaction/economy logs
chat Teal (#5793266) :speech_balloon: Chat/communication logs

Configuration

Configure the cv.log module in resources/[base]/cv_framework/config.lua:

Config.Log = {
    botName = "[CasualV] SystemBot",                    -- Discord bot name
    botAvatar = "https://img.casualv.de/assets/...",   -- Discord bot avatar URL

    generalWebhook = "https://discord.com/api/...",    -- Default webhook for unmapped channels

    channels = {
        ["general"] = "https://discord.com/api/webhooks/...",
        ["player-join-leave"] = "https://discord.com/api/webhooks/...",
        ["transactions"] = "https://discord.com/api/webhooks/...",
        ["inventory"] = "https://discord.com/api/webhooks/...",
        ["commands"] = "https://discord.com/api/webhooks/...",
        ["errors"] = "https://discord.com/api/webhooks/...",
        ["anticheat"] = "https://discord.com/api/webhooks/...",
    }
}

Channel Configuration

Each channel can have its own webhook URL. If a channel is not defined, the generalWebhook is used as a fallback.

Usage

Basic Logging

cv.log(title, description, logType, channel, fields, playerData)

Parameters

Parameter Type Required Description
title string Yes Log title/header
description string Yes Detailed log description
logType string No Log type (default: "info") - see Log Types table
channel string No Channel name for webhook routing (default: "general")
fields table No Array of Discord embed fields for additional data
playerData table No Player context - see Player Data table

Player Data Structure

playerData = {
    charId = 123,              -- Character ID (from database)
    citizenId = "ABC12345",    -- Character citizenship ID
    userId = "license:...",    -- Steam account ID
    name = "John Doe"          -- Player display name
}

Examples

Simple Information Log

cv.log("Server Started", "Game server initialization complete", "info", "general")

Player Join Event

local player = CVPlayer.GetPlayer(source)
cv.log(
    "Player Joined",
    string.format("Player %s (Char: %s) connected to server", player.name, player.citizenid),
    "player",
    "player-join-leave",
    {},
    {
        charId = player.charId,
        citizenId = player.citizenid,
        userId = player.userId,
        name = player.name
    }
)

Transaction Log with Extra Fields

cv.log(
    "Money Transfer",
    string.format("Player transferred $%d to another player", amount),
    "economy",
    "transactions",
    {
        {
            name = "Amount",
            value = "$" .. amount,
            inline = true
        },
        {
            name = "From",
            value = fromPlayerName,
            inline = true
        },
        {
            name = "To",
            value = toPlayerName,
            inline = true
        }
    },
    {
        charId = player.charId,
        citizenId = player.citizenid,
        userId = player.userId,
        name = player.name
    }
)

Error Logging

cv.log(
    "Database Error",
    "Failed to execute query: [Error details here]",
    "error",
    "errors",
    {
        {
            name = "Error Code",
            value = "DB_001",
            inline = true
        },
        {
            name = "Query",
            value = "```sql\nSELECT * FROM...\n```",
            inline = false
        }
    }
)

Admin Action Log

cv.log(
    "Player Kicked",
    string.format("Admin kicked player %s for: %s", playerName, reason),
    "admin",
    "commands",
    {
        {
            name = "Admin",
            value = adminName,
            inline = true
        },
        {
            name = "Reason",
            value = reason,
            inline = true
        }
    }
)

Database Schema

Logs are stored in the system_logs table with the following structure:

CREATE TABLE `system_logs` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `log_type` varchar(50) NOT NULL,              -- Log type (info, error, etc.)
    `channel` varchar(50) NOT NULL,               -- Discord channel identifier
    `title` varchar(255) NOT NULL,                -- Log title
    `description` text,                           -- Full description
    `char_id` int(11) DEFAULT NULL,               -- Character ID (if applicable)
    `citizen_id` varchar(50) DEFAULT NULL,        -- Character citizenship ID
    `user_id` varchar(100) DEFAULT NULL,          -- User Steam ID
    `player_name` varchar(100) DEFAULT NULL,      -- Player display name
    `metadata` JSON,                              -- Additional fields as JSON
    `created_at` timestamp DEFAULT current_timestamp(),  -- Creation timestamp
    PRIMARY KEY (`id`),
    KEY `log_type` (`log_type`),
    KEY `channel` (`channel`),
    KEY `char_id` (`char_id`),
    KEY `citizen_id` (`citizen_id`),
    KEY `user_id` (`user_id`),
    KEY `created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

Querying Logs

-- Get all error logs from the last 24 hours
SELECT * FROM system_logs 
WHERE log_type = 'error' 
AND created_at >= DATE_SUB(NOW(), INTERVAL 1 DAY)
ORDER BY created_at DESC;

-- Get all actions by a specific character
SELECT * FROM system_logs 
WHERE char_id = 123 
ORDER BY created_at DESC;

-- Get all transaction logs for a specific player
SELECT * FROM system_logs 
WHERE citizen_id = 'ABC12345' 
AND log_type IN ('economy', 'transactions')
ORDER BY created_at DESC;

-- Count logs by type in the last week
SELECT log_type, COUNT(*) as count 
FROM system_logs 
WHERE created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)
GROUP BY log_type;

Discord Integration

Features

  • Real-Time Notifications: Logs are sent to Discord immediately
  • Embed Formatting: Each log is formatted as a rich Discord embed with:
  • Title with type icon
  • Description
  • Color-coded by log type
  • Optional fields for additional data
  • Server name in footer
  • Timestamp of event
  • Bot avatar

Webhook Setup

  1. Create Discord channels for each log category
  2. Create webhooks for each channel
  3. Add webhook URLs to Config.Log.channels in config.lua
  4. Use the channel name in cv.log() calls to route logs appropriately

Example Discord Embed

` Icon [ADMIN] Player Kicked ├─ Description: Admin kicked player John for: Spam ├─ Fields: │ ├─ Admin: AdminName │ ├─ Reason: Spam ├─ Footer: CasualV Default Server └─ Timestamp: 2026-02-07T14:30:45Z