void sendLog(const char *msg, uint8_t loglevel)
{
    char buf[200];
    char buf2[221];
    bool timeIsValid = false;
    strlcpy(buf, msg, sizeof(buf));

#ifdef ENABLE_FEATURE_NTP_TIME
    static char tbuf[20];
    if (confTime.ntpEnable)
    {
        updateTime();
        if (lt.tm_year > 70)
        { // lt.tm_year = years since 1900, before NTP is synced = 70
            //strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %H:%M:%S", &lt);
            strftime(tbuf, sizeof(tbuf), "%H:%M:%S", &lt);
            sprintf(buf2, "[%s] %s\r\n", tbuf, buf);
            timeIsValid = true;
        }
    }
#endif

    if (!timeIsValid)
    {
        unsigned long tmpMillis;
        unsigned long tmpSecs;
        unsigned int restMillis;
        tmpMillis = millis();
        tmpSecs = tmpMillis / 1000;
        restMillis = tmpMillis - (tmpSecs * 1000);
        //tmpSecs = millis() / 1000;

        if (tmpSecs < 10000)
            sprintf(buf2, "[%04lu.%3u] %s\r\n", tmpSecs, restMillis, buf);
        else
            sprintf(buf2, "[%08lu] %s\r\n", tmpSecs, buf);
    }

    if (loglevel <= confLog.logLevelSerial)
        Serial.print(buf2);

    if (confMqtt.mqtt_enable && mqttclient.state() == 0)
    {
        if (loglevel <= confLog.logLevelMqtt)
            
            mqttclient.publish(mqtt_topic_log, buf, false);
    }

#ifdef ENABLE_FEATURE_WSCONSOLE
    yield();
    if (confWeb.wsConsole && webSocket.connectedClients() > 0)
    {
        if (loglevel <= confLog.logLevelWeb)
            webSocket.broadcastTXT(buf2);
    }
#endif

#ifdef ENABLE_FEATURE_WEB_CONSOLE
    if (confWeb.wConsole && loglevel <= confLog.logLevelWeb)
    {
        char buf3[250];
        //char webLogBuffer[2000];
        //unsigned int webLogBuffer_index=0;
        sprintf(buf3, "{%u}%s", webLogBuffer_index, buf2);

        //Serial.print("DEV: '");
        //Serial.print(buf3);
        //Serial.println("'");

        //char * posmsg2 = 0;
        //posmsg2 = strstr(webLogBuffer,'\n');
        //Serial.print("POS=");
        //Serial.println((int)posmsg2);

        bool done = false;
        while (!done)
        {
            int currSize = strlen(webLogBuffer);
            int addSize = strlen(buf3);
            int maxSize = sizeof(webLogBuffer) - 10;

            //if(addSize < 100) addSize = 100;
            //Serial.print("   currSize="); Serial.print(currSize);
            //Serial.print("   addSize="); Serial.print(addSize);
            //Serial.print("   maxSize="); Serial.print(maxSize);

            if ((currSize + addSize) >= maxSize)
            {
                //Serial.print("   buf FULL, size=");
                //Serial.print(currSize);
                //Serial.print("   removing 1.msg...");

                int posMsg2 = 0;
                while (posMsg2 < currSize)
                {
                    if (webLogBuffer[posMsg2] == '\n')
                    {
                        posMsg2++;
                        break;
                    }
                    else
                        posMsg2++;
                }

                //Serial.print("   posMsg2=");
                //Serial.print(posMsg2);

                int oldSize = strlen(webLogBuffer);
                int c = 0;
                while (c < (oldSize - posMsg2))
                {
                    webLogBuffer[c] = webLogBuffer[posMsg2 + c];
                    //Serial.println();
                    //Serial.print(webLogBuffer[posMsg2 + c]);
                    //Serial.print("  [");
                    //Serial.print(posMsg2 + c);
                    //Serial.print("] -> [");
                    //Serial.print(c);
                    //Serial.print("]");
                    c++;
                }
                webLogBuffer[c] = '\0';
                //Serial.print("   removed msg 1, new size=");
                //Serial.print(strlen(webLogBuffer));
            }
            else
            {
                done = true;
                //Serial.println("   done");
            }
            //Serial.println();
        }

        if ((strlen(webLogBuffer) + strlen(buf3)) < (sizeof(webLogBuffer) - 10))
        {
            //Serial.print("   add msg to buf");
            int c = 0;
            int offset = strlen(webLogBuffer);
            //Serial.print("   offset=");
            //Serial.print(offset);

            int size = strlen(buf3);
            while (c < size)
            {
                if ((c + offset) < (int)sizeof(webLogBuffer))
                {
                    webLogBuffer[c + offset] = buf3[c];
                    c++;
                }
                else
                    break;
            }
            webLogBuffer[c + offset] = '\0';

            //Serial.print("AFTER 2: ");
            //Serial.println(webLogBuffer);

            webLogBuffer_index++;
        }
    }
#endif
}

void sendLog(const __FlashStringHelper *msg, uint8_t loglevel)
{
    char buf[201];
    PGM_P p = reinterpret_cast<PGM_P>(msg);
    size_t n = 0;
    while (1)
    {
        unsigned char c = pgm_read_byte(p++);
        if (c == 0)
        {
            buf[n] = c;
            break;
        }
        else if (n >= sizeof(buf) - 1)
        {
            break;
        }
        else
        {
            buf[n] = c;
            n++;
        }
    }
    sendLog(buf, loglevel);
}
