Skip to content

Commit

Permalink
Merge pull request #1 from Tiaansu/fetch-log
Browse files Browse the repository at this point in the history
Fetch logs, case sensitive support, automatic cleanup of logs result
  • Loading branch information
Tiaansu authored Dec 15, 2024
2 parents 56c292d + 2bdb054 commit 4ae3390
Show file tree
Hide file tree
Showing 14 changed files with 488 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,4 @@ You can check this [repository](https://github.com/Tiaansu/greet-component) for
## Thanks to
- [Amir's omp-node](https://github.com/AmyrAhmady/omp-node) (I copied it's `include` style so other components can use this component)
- [maddinatOr's samp-log-core](https://github.com/maddinat0r/samp-log-core) (most of the code were from this project)
- [Toiletduck / Eksqtr](https://github.com/eksqtr) (big thanks to this person. Many ideas were from him)
10 changes: 10 additions & 0 deletions include/omp-logger.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ namespace OmpLogger
}

struct IOmpLog;
struct PaginatedResult;

static const UID OmpLoggerComponent_UID = UID(0xAB3BC9C4E583C8B4);
class IOmpLoggerComponent : public IComponent
Expand Down Expand Up @@ -68,6 +69,8 @@ struct IOmpLog

virtual uint32_t getColor() const = 0;

virtual PaginatedResult fetchLogs(int linesPerPage, int pageStart, const std::string& searchTerm, bool caseSensitive) const = 0;

virtual bool log(AMX* amx, OmpLogger::ELogLevel level, StringView message) const = 0;

virtual bool log(OmpLogger::ELogLevel level, StringView message) const = 0;
Expand Down Expand Up @@ -103,4 +106,11 @@ class OmpLoggerManager

private:
IOmpLoggerComponent* ompLogger_ = nullptr;
};

struct PaginatedResult
{
std::vector<std::string> lines;
int currentPage;
int totalPages;
};
14 changes: 14 additions & 0 deletions omp-logger.inc
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,17 @@ native bool:Logger_Info(Logger:id, const format[], OPEN_MP_TAGS:...);
native bool:Logger_Warning(Logger:id, const format[], OPEN_MP_TAGS:...);
native bool:Logger_Error(Logger:id, const format[], OPEN_MP_TAGS:...);
native bool:Logger_Fatal(Logger:id, const format[], OPEN_MP_TAGS:...);

// Logs result
native Logger_FetchLogs(playerid, Logger:logger, amount, pageStart, const callback[], const search[] = "", bool:caseSensitive = true);
native Logger_GetResult(LogsResult:result, row, logs[], size = sizeof logs);
native Logger_FreeResult(LogsResult:result);

// Cleanup results once they go out of scope
stock operator~(const LogsResult:result[], len)
{
for (new i = 0; i < len; ++ i)
{
Logger_FreeResult(result[i]);
}
}
36 changes: 34 additions & 2 deletions src/component.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <fmt/format.h>
#include "component.hpp"
#include "helpers/utils.hpp"
#include "threaded-queue.hpp"

// API
IOmpLog* OmpLoggerComponent::createLogger(StringView name, int32_t color, OmpLogger::ELogLevel level, bool isPlugin)
Expand All @@ -26,7 +27,7 @@ IOmpLog* OmpLoggerComponent::createLogger(StringView name, int32_t color, OmpLog
color = 0;
}

std::FILE* file = ::fopen(filepath.c_str(), "a");
std::FILE* file = ::fopen(filepath.c_str(), "a+");
if (file == nullptr)
{
core_->logLn(LogLevel::Error, "Failed to open log file \"%s\".", filepath.c_str());
Expand All @@ -48,6 +49,24 @@ IOmpLog* OmpLoggerComponent::getLogger(int id)
return pool_.get(id);
}

// Fetch logs
ILogsResult* OmpLoggerComponent::initLogsResult(std::vector<std::string> logs)
{
return logsResults_.emplace(logs);
}

bool OmpLoggerComponent::deleteLogsResult(ILogsResult* result)
{
int id = static_cast<ILogsResult*>(result)->getID();
logsResults_.release(id, false);
return true;
}

ILogsResult* OmpLoggerComponent::getLogsResult(int id)
{
return logsResults_.get(id);
}

// Callbacks
void OmpLoggerComponent::onLoad(ICore* c)
{
Expand All @@ -68,6 +87,7 @@ void OmpLoggerComponent::onInit(IComponentList* components)
setAmxFunctions(pawn_->getAmxFunctions());
setAmxLookups(components);
pawn_->getEventDispatcher().addEventHandler(this);
core_->getEventDispatcher().addEventHandler(this);

IConfig& config = core_->getConfig();
isLogLevelNameCapitalized_ = (config.getBool("logger.log_level_capitalized")) ? (*config.getBool("logger.log_level_capitalized")) : false;
Expand Down Expand Up @@ -193,6 +213,8 @@ void OmpLoggerComponent::free()
serverLoggerFile_ = nullptr;
}

ThreadedQueue::Get()->Destroy();

delete this;
core_->printLn("[omp-logger] Logger released.");
}
Expand All @@ -210,7 +232,13 @@ void OmpLoggerComponent::onAmxLoad(IPawnScript& script)

void OmpLoggerComponent::onAmxUnload(IPawnScript& script)
{
debugEraseAMX(script.GetAMX());
AMX* amx = script.GetAMX();
debugEraseAMX(amx);
}

void OmpLoggerComponent::onTick(Microseconds elapsed, TimePoint now)
{
ThreadedQueue::Get()->Process();
}

OmpLoggerComponent::~OmpLoggerComponent()
Expand All @@ -219,6 +247,10 @@ OmpLoggerComponent::~OmpLoggerComponent()
{
pawn_->getEventDispatcher().removeEventHandler(this);
}
if (core_)
{
core_->getEventDispatcher().removeEventHandler(this);
}
}

// API - Config
Expand Down
13 changes: 13 additions & 0 deletions src/component.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@
#include "omp-logger.hpp"
#include "omp-log.hpp"
#include "debug-manager.hpp"
#include "logs-result.hpp"

class OmpLoggerComponent final
: public IOmpLoggerComponent
, public PawnEventHandler
, public CoreEventHandler
{
private:
ICore* core_ = nullptr;
Expand All @@ -23,6 +25,8 @@ class OmpLoggerComponent final

MarkedPoolStorage<OmpLog, IOmpLog, 1, 1000> pool_;

MarkedPoolStorage<LogsResult, ILogsResult, 1, 5000> logsResults_;

inline static OmpLoggerComponent* instance_ = nullptr;

// configs
Expand All @@ -44,6 +48,13 @@ class OmpLoggerComponent final

IOmpLog* getLogger(int id) override;

// Fetch logs
ILogsResult* initLogsResult(std::vector<std::string> logs);

bool deleteLogsResult(ILogsResult* result);

ILogsResult* getLogsResult(int id);

// Component
StringView componentName() const override
{
Expand All @@ -54,6 +65,8 @@ class OmpLoggerComponent final
{
return SemanticVersion(0, 0, 1, 0);
}

void onTick(Microseconds elapsed, TimePoint now) override;

void onLoad(ICore* c) override;

Expand Down
19 changes: 19 additions & 0 deletions src/logs-result.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include "logs-result.hpp"
#include "component.hpp"

using namespace Impl;

int LogsResult::getID() const
{
return poolID;
}

std::string LogsResult::getLog(int row) const
{
return logs_.at(row);
}

LogsResult::LogsResult(std::vector<std::string> logs)
: logs_(std::move(logs))
{
}
29 changes: 29 additions & 0 deletions src/logs-result.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#pragma once

#include <sdk.hpp>
#include <Impl/pool_impl.hpp>

using namespace Impl;

struct ILogsResult
{
virtual int getID() const = 0;

virtual std::string getLog(int row) const = 0;
};

class LogsResult final
: public ILogsResult
, public PoolIDProvider
, public NoCopy
{
private:
std::vector<std::string> logs_;

public:
int getID() const override;

std::string getLog(int row) const override;

LogsResult(std::vector<std::string> logs);
};
38 changes: 38 additions & 0 deletions src/natives.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
#include <algorithm>
#include <string>
#include <vector>
#include <thread>

#include <sdk.hpp>
#include <Server/Components/Pawn/Impl/pawn_natives.hpp>

#include "component.hpp"
#include "natives.hpp"
#include "omp-logger.hpp"
#include "threaded-queue.hpp"
#include "helpers/format.hpp"

SCRIPT_API(Logger_Create, int(std::string const& name, int32_t color, OmpLogger::ELogLevel level))
Expand Down Expand Up @@ -56,4 +59,39 @@ SCRIPT_API(Logger_Fatal, bool(IOmpLog& logger, cell const* format))
{
AMX* amx = GetAMX();
return logger.log(amx, OmpLogger::ELogLevel::Fatal, AmxStringFormatter(format, amx, GetParams(), 2));
}

SCRIPT_API(Logger_FetchLogs, bool(IPlayer& player, IOmpLog& logger, int linesPerPage, int pageStart, std::string const& callback, std::string const& searchTerm, bool caseSensitive))
{
AMX* amx = GetAMX();

auto func = [&player, &logger, amx, callback, searchTerm, linesPerPage, pageStart, caseSensitive]() {

int funcIDX = 0;
if (!amx_FindPublic(amx, callback.c_str(), &funcIDX))
{
PaginatedResult result = logger.fetchLogs(linesPerPage, pageStart, searchTerm, caseSensitive);
ILogsResult* logsResult = OmpLoggerComponent::Get()->initLogsResult(result.lines);
amx_Push(amx, result.totalPages);
amx_Push(amx, result.currentPage);
amx_Push(amx, (int)result.lines.size());
amx_Push(amx, logsResult->getID());
amx_Push(amx, logger.getID());
amx_Push(amx, player.getID());
amx_Exec(amx, NULL, funcIDX);
}
};
ThreadedQueue::Get()->Dispatch(func);
return 1;
}

SCRIPT_API(Logger_GetResult, int(ILogsResult& result, int row, OutputOnlyString& logs))
{
logs = result.getLog(row);
return std::get<StringView>(logs).length();
}

SCRIPT_API(Logger_FreeResult, bool(ILogsResult& result))
{
return OmpLoggerComponent::Get()->deleteLogsResult(&result);
}
100 changes: 100 additions & 0 deletions src/natives.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,104 @@ namespace pawn_natives
ParamCast(AMX*, cell*, int) = delete;
ParamCast() = delete;
};

// Logs result
template <>
struct ParamLookup<ILogsResult>
{
static ILogsResult* Val(cell ref) noexcept
{
if (auto pool = OmpLoggerComponent::Get())
{
return pool->getLogsResult(ref);
}
return nullptr;
}
};

template <>
class ParamCast<ILogsResult*>
{
public:
ParamCast(AMX* amx, cell* params, int idx) noexcept
{
value_ = ParamLookup<ILogsResult>::Val(params[idx]);
}

~ParamCast()
{
}

ParamCast(ParamCast<ILogsResult*> const&) = delete;
ParamCast(ParamCast<ILogsResult*>&&) = delete;

operator ILogsResult*()
{
return value_;
}

bool Error() const
{
return false;
}

static constexpr int Size = 1;

private:
ILogsResult* value_;
};

template <>
class ParamCast<ILogsResult&>
{
public:
ParamCast(AMX* amx, cell* params, int idx)
{
value_ = ParamLookup<ILogsResult>::Val(params[idx]);
if (value_ == nullptr)
{
AmxFuncCallInfo dest;
if (!DebugManager::Get()->GetFunctionCall(amx, amx->cip, dest))
{
OmpLoggerComponent::Get()->getCore()->logLn(LogLevel::Warning, "Invalid logs result id %i", static_cast<int>(params[idx]));
}
else
{
OmpLoggerComponent::Get()->getCore()->logLn(LogLevel::Warning, "Invalid logs result id %i (%s:%i)", static_cast<int>(params[idx]), dest.file, static_cast<int>(dest.line));
}
error_ = true;
}
}

~ParamCast()
{
}

ParamCast(ParamCast<ILogsResult&> const&) = delete;
ParamCast(ParamCast<ILogsResult&>&&) = delete;

operator ILogsResult&()
{
return *value_;
}

bool Error() const
{
return error_;
}

static constexpr int Size = 1;

private:
ILogsResult* value_;
bool error_ = false;
};

template <>
class ParamCast<const ILogsResult&>
{
public:
ParamCast(AMX*, cell*, int) = delete;
ParamCast() = delete;
};
}
Loading

0 comments on commit 4ae3390

Please sign in to comment.