Rust (Oxide)
Add ServerOps logging and media uploads to your Rust server using Oxide / uMod.
Rust: Getting started with Oxide / uMod
This guide adds ServerOps integration to your Rust server using an Oxide (uMod) plugin. You will be able to log player events and upload screenshot evidence directly from your server.
Before you start
- Complete Getting your API token. You need a token with
logs:writeand/ormedia:writescope. - Your server must have Oxide / uMod installed.
Create the plugin
- On your server, navigate to
oxide/plugins/. - Create a new file named
ServerOps.cs. - Paste the following code and replace the placeholder token in
LoadDefaultConfig:
using System.Collections.Generic;
using Oxide.Core.Libraries.Covalence;
namespace Oxide.Plugins
{
[Info("ServerOps", "YourName", "1.0.0")]
[Description("ServerOps.gg integration for logs and media uploads.")]
public class ServerOps : CovalencePlugin
{
private string ApiToken => Config["ApiToken"]?.ToString() ?? "";
protected override void LoadDefaultConfig()
{
Config["ApiToken"] = "so_live_..."; // Replace with your token
}
private void SendLog(string level, string message, Dictionary<string, object> meta = null)
{
var payload = new Dictionary<string, object>
{
["level"] = level,
["message"] = message,
["meta"] = meta ?? new Dictionary<string, object>()
};
webrequest.Enqueue(
"https://api.serverops.gg/v1/logs",
Newtonsoft.Json.JsonConvert.SerializeObject(payload),
(code, response) =>
{
if (code != 201)
Puts($"[ServerOps] Log failed ({code}): {response}");
},
this,
RequestMethod.POST,
new Dictionary<string, string>
{
["Authorization"] = $"Bearer {ApiToken}",
["Content-Type"] = "application/json"
}
);
}
// Log player connections
private void OnUserConnected(IPlayer player)
{
SendLog("info", "Player connected", new Dictionary<string, object>
{
["name"] = player.Name,
["id"] = player.Id,
["address"] = player.Address
});
}
// Log player disconnections
private void OnUserDisconnected(IPlayer player, string reason)
{
SendLog("info", "Player disconnected", new Dictionary<string, object>
{
["name"] = player.Name,
["id"] = player.Id,
["reason"] = reason
});
}
// Log bans
private void OnUserBanned(string name, string id, string address, string reason)
{
SendLog("warn", "Player banned", new Dictionary<string, object>
{
["name"] = name,
["id"] = id,
["reason"] = reason
});
}
}
}Configure your token
After placing the file, load the plugin with oxide.load ServerOps in your server console. This creates a config file at oxide/config/ServerOps.json.
Open that file and replace the placeholder with your actual token:
{
"ApiToken": "so_live_..."
}Reload the plugin with oxide.reload ServerOps.
Never share your oxide/config/ServerOps.json file publicly or commit it to a public repository. It contains your API token.
Adding logs to your other plugins
If you have other Oxide plugins and want them to send logs, call SendLog from the ServerOps plugin class directly, or copy the SendLog method into your other plugins using the same pattern.
Uploading evidence files
To upload a file (for example, a screenshot you captured with another tool), encode it as base64 and POST it to the /media/base64 endpoint:
private void UploadBase64File(string base64Data, string filename)
{
var payload = Newtonsoft.Json.JsonConvert.SerializeObject(new Dictionary<string, object>
{
["file"] = base64Data,
["filename"] = filename
});
webrequest.Enqueue(
"https://api.serverops.gg/v1/media/base64",
payload,
(code, response) =>
{
if (code == 200 || code == 201)
Puts($"[ServerOps] Uploaded: {response}");
else
Puts($"[ServerOps] Upload failed ({code}): {response}");
},
this,
RequestMethod.POST,
new Dictionary<string, string>
{
["Authorization"] = $"Bearer {ApiToken}",
["Content-Type"] = "application/json"
}
);
}Viewing your data
Logs and uploads appear in your ServerOps dashboard.
Troubleshooting
"ApiToken is empty": Open oxide/config/ServerOps.json and check that the token is present and correct.
Logs show status 401: Your token is invalid or does not have the required scope. Create a new token with logs:write scope.
Plugin fails to compile: Make sure Oxide is up to date and the filename is ServerOps.cs (case-sensitive on Linux).