Sphereserver / Source-X

Ultima Online server emulator
Apache License 2.0
57 stars 45 forks source link

[Feature Request] Colored Serv & Src Log System #1158

Closed canerksk closed 1 month ago

canerksk commented 11 months ago

I think there should be a logging system that includes character information, just like there is server logging. Additionally, if we color them, we will give the logs a visual order of importance, and the logs may be easier to read and examine.

eg;

First of all, we need to add the color parameter to the log functions;

protected:
    virtual int EventStr(dword dwMask, lpctstr pszMsg, ConsoleTextColor LogColor) = 0;

    int VEvent(dword dwMask, lpctstr pszFormat, va_list args, ConsoleTextColor LogColor);

public:
    int _cdecl Event( dword dwMask, lpctstr pszFormat, ... ) __printfargs(3,4);
    int _cdecl EventChar(ConsoleTextColor LogColor, lpctstr pszFormat, ...) __printfargs(2, 3);
    int _cdecl EventDebug(lpctstr pszFormat, ...) __printfargs(2,3);
    int _cdecl EventError(lpctstr pszFormat, ...) __printfargs(2,3);
    int _cdecl EventWarn(lpctstr pszFormat, ...) __printfargs(2,3);

int CEventLog::VEvent(dword dwMask, lpctstr pszFormat, va_list args, ConsoleTextColor LogColor)
{
    if (pszFormat == nullptr || pszFormat[0] == '\0')
        return 0;

    tchar* pszTemp = Str_GetTemp();
    size_t len = vsnprintf(pszTemp, (STR_TEMPLENGTH - 1), pszFormat, args);
    if (! len)
        Str_CopyLimitNull(pszTemp, pszFormat, (STR_TEMPLENGTH - 1));

    // This get rids of exploits done sending 0x0C to the log subsytem.
    // tchar *   pFix;
    // if ( ( pFix = strchr( pszText, 0x0C ) ) )
    //  *pFix = ' ';

    return EventStr(dwMask, pszTemp, LogColor ? LogColor : CTCOL_DEFAULT);
}

int CEventLog::Event(dword dwMask, lpctstr pszFormat, ...)
{
    va_list vargs;
    va_start(vargs, pszFormat);
    int iret = VEvent(dwMask, pszFormat, vargs, CTCOL_DEFAULT);
    va_end(vargs);
    return iret;
}

int CEventLog::EventDebug(lpctstr pszFormat, ...)
{
    va_list vargs;
    va_start(vargs, pszFormat);
    int iret = VEvent(LOGM_DEBUG|LOGM_NOCONTEXT, pszFormat, vargs, CTCOL_DEFAULT);
    va_end(vargs);
    return iret;
}

int CEventLog::EventChar(ConsoleTextColor LogColor,lpctstr pszFormat, ...)
{
    va_list vargs;
    va_start(vargs, pszFormat);
    int iret = VEvent(LOGL_CHAR, pszFormat, vargs, LogColor);
    va_end(vargs);
    return iret;
}

int CEventLog::EventError(lpctstr pszFormat, ...)
{
    va_list vargs;
    va_start(vargs, pszFormat);
    int iret = VEvent(LOGL_ERROR, pszFormat, vargs, CTCOL_DEFAULT);
    va_end(vargs);
    return iret;
}

int CEventLog::EventWarn(lpctstr pszFormat, ...)
{
    va_list vargs;
    va_start(vargs, pszFormat);
    int iret = VEvent(LOGL_WARN, pszFormat, vargs, CTCOL_DEFAULT);
    va_end(vargs);
    return iret;
}

Then we can use the newly added EventChar function here.


        case CHV_LOG:
        {
            lpctstr LogText = s.GetArgStr();
            const CPointMap& pt = GetTopPoint();

            if (m_pPlayer)
            {
                CAccount* pAccount = m_pPlayer->GetAccount();
                CClient* pClient = pAccount->FindClient();
                g_Log.EventChar(m_LogColor, "[Priv=%d, Account=%s, CharName=%s, UID=%u, Region=%s(%s), IP=%s, ClientVersion=%d]\n'%s'\n", GetPrivLevel(), pAccount->GetName(), GetName(), (dword)GetUID(), GetRegion()->GetName(), pt.WriteUsed(), pAccount->m_Last_IP.GetAddrStr(), pClient->GetNetState()->getReportedVersion(), LogText);
            }
            else if (m_pNPC)
            {
                g_Log.EventChar(m_LogColor, "[Name=%s, UID=%u, Owner=%u, Region=%s(%s)]\n'%s'\n", GetName(), (dword)GetUID(), GetOwner()->GetName(), (dword)GetOwner()->GetUID(), GetRegion()->GetName(), pt.WriteUsed(), LogText);
            }
            break;
        }

and Char LogColor

// set

        case CHC_LOGCOLOR:
        {
            int iVal = s.GetArgVal();
            if (iVal < 0 && iVal > 8)
                return false;
            m_LogColor = (ConsoleTextColor)iVal;
        }
        break;

// get


        case CHC_LOGCOLOR:
            sVal.FormatVal(m_LogColor);
            break;

CChar.h

ConsoleTextColor m_LogColor;

CChar_props.tbl

ADD(LOGCOLOR, "LOGCOLOR")

Preview;

image

DEFNAMES


[DEFNAME console_text_color]
CTCOL_DEFAULT   0
CTCOL_RED       1
CTCOL_GREEN     2
CTCOL_YELLOW    3
CTCOL_BLUE      4
CTCOL_MAGENTA   5
CTCOL_CYAN      6
CTCOL_WHITE     7
CTCOL_QTY       8

Usage;

[function logtest]
src.logcolor <def.CTCOL_QTY>
src.log Log test Qty

src.logcolor <def.CTCOL_WHITE>
src.log Log test White

src.logcolor <def.CTCOL_CYAN>
src.log Log test Cyan

src.logcolor <def.CTCOL_MAGENTA>
src.log Log test Magenta

src.logcolor <def.CTCOL_BLUE>
src.log Log test Blue

src.logcolor <def.CTCOL_DEFAULT>
src.log Log test Default

src.logcolor <def.CTCOL_RED>
src.log Log test Red

src.logcolor <def.CTCOL_GREEN>
src.log Log test Green

src.logcolor <def.CTCOL_YELLOW>
src.log Log test Yellow

serv.log Test log

The codes here are purely examples. Although many have been tested, some may need to be rewritten.

cbnolok commented 11 months ago

Imho, adding a CObjBase LOG function is redundant, since you can easily create a custom script function printing all the infos you need and print them using SERV.LOG; moreover, you can easily customize the info being shown, while doing that in the source wouldn't be so easy. That said, the colored log message feature is a good one, i'd just extend SERV.LOG to support choosing colors (like how it's done with the SAY function, prepending @color).

canerksk commented 11 months ago

I still don't think the current log system is convenient. On an active server, a daily log file can reach large sizes (I have seen log files reaching sizes of 10 - 50 MB). When this is the case, we spend a very long time trying to find what we are looking for in the log file. I think some changes should be tailored to high volume servers. Since Sphere-X is not a high-volume active server at the moment, it is not possible to fully understand this, but I can say that this is a real problem. An additional log script puts extra strain on the server, and the script profiler can increase the use of this special log function to millions. It may be necessary to take a look at this log system. Perhaps a separate log system for the account or character can be created with an additional setting added to sphere.ini.

For example.


logs/sphere2023-09-23.log
logs/<account>/sphere2023-09-23.log
logs/<account>/<charuid>/sphere2023-09-23.log

LOGM_ACCOUNT           0xxx // 
LOGM_ACCOUNT_CHARS          0xxxx 

Of course, this can be done with additional functions or write/delete file, but as I said, the important thing here is to create a detailed/advanced logging system.

If it will cause a problem, only coloring can be done, at least it will make console tracking easier.

Jhobean commented 11 months ago

Color change nothing on the log file because there no color on the .log.

On my side, I add keyword at the beginning of line. Ex: serv.log CHAR: character x stone from x

After that I do search for CHAR: and I see only these line.

What you propose(save in different file) it's a good feature request but to be honest it will be priority 5. If you propose a PR we can check better.

canerksk commented 11 months ago

Color change nothing on the log file because there no color on the .log.

On my side, I add keyword at the beginning of line. Ex: serv.log CHAR: character x stone from x

After that I do search for CHAR: and I see only these line.

What you propose(save in different file) it's a good feature request but to be honest it will be priority 5. If you propose a PR we can check better.

Of course, the console colors/style cannot be transferred to the notepad. We are actually talking about two different problems here, one of which is to follow the console in real time and the other is to find something previously logged more easily by searching. Colored console logs in simultaneous log tracking can enable us to intervene instantly, at least in critical transactions.

Separating other logs can also make it easier for us to find what we are looking for. For example, when I want to search for how many times an account has performed a transaction, I can directly go to the logs of that account and see it, but now I need to find it among thousands of lines. A similar example with the ServUO logging system I can give.

As I said, it is not a must, but I think the log system should also be improved, at least the idea of keeping all the server's logs in one place does not seem very healthy to me, or this should be optional.

For example, color and other parameters can be added to the serv.log command, such as showing on the console but not write log file, showing and writing on the console. This is a separate idea.

serv.log @color,<write 0/1>,<show 0/1> text

etc.

https://github.com/Sphereserver/Source-X/assets/10347131/ccbe6ec5-bd9a-4491-952d-69adda8e29ad

cbnolok commented 1 month ago

Closing as addressed.