Exemple #1
0
static
rc_t CC sts_print(KFmtHandler* formatter, const KStsFmtFlags flags, KWrtHandler* writer, const char* msg, va_list args)
{
    rc_t rc = 0;
    char* nbuffer;
    size_t num_writ, remaining;

    uint32_t envc = 0;
    wrt_nvp_t envs[5];
    char ebuffer[2048];
    char mbuffer[2048];
    KFmtWriter fmtwrt;

    assert(formatter != NULL);
    assert(writer != NULL);

    fmtwrt = formatter->formatter;
    if( fmtwrt == NULL ) {
        fmtwrt = KStsDefaultFormatter;
    }
    if( fmtwrt == KStsDefaultFormatter && writer->writer == NULL ) {
        /* default formatting with NULL writer -> silence */
        return rc;
    }
    nbuffer = (char*)ebuffer;
    remaining = sizeof(ebuffer);
    do {
#define FIX_UP() if(rc){break;} remaining -= num_writ; nbuffer += num_writ
        if( flags & (kstsFmtTimestamp | kstsFmtLocalTimestamp) ) {
            if( flags & kstsFmtLocalTimestamp ) {
                rc = LogSimpleTimestamp(nbuffer, remaining, &num_writ);
            } else {
                rc = LogTimestamp(nbuffer, remaining, &num_writ);
            }
            nbuffer[num_writ++] = '\0';
            envs[envc].name = "timestamp";
            envs[envc++].value = nbuffer;
            FIX_UP();
        }
        if( flags & kstsFmtPid ) {
            rc = LogPID(nbuffer, remaining, &num_writ);
            nbuffer[num_writ++] = '\0';
            envs[envc].name = "pid";
            envs[envc++].value = nbuffer;
            FIX_UP();
        }
        if( flags & kstsFmtAppName ) {
            rc = LogAppName(nbuffer, remaining, &num_writ);
            nbuffer[num_writ++] = '\0';
            envs[envc].name = "app";
            envs[envc++].value = nbuffer;
            FIX_UP();
        }
        if( flags & kstsFmtAppVersion ) {
            rc = LogAppVersion(nbuffer, remaining, &num_writ);
            nbuffer[num_writ++] = '\0';
            envs[envc].name = "version";
            envs[envc++].value = nbuffer;
            FIX_UP();
        }
#undef FIX_UP
    } while(false);
    /* env must have one spare element for message added text below */
    if( rc == 0 && envc >= (sizeof(envs)/sizeof(envs[0])) ) {
        rc = RC(rcRuntime, rcLog, rcLogging, rcTable, rcInsufficient);
    }
    nbuffer = (char*)mbuffer;
    remaining = sizeof(mbuffer);

    if( rc == 0 ) {
        if( flags & kstsFmtMessage ) {
            if( msg == NULL || msg[0] == '\0' ) {
                msg = "empty status message";
            }
            do {
                va_list args_copy;
                va_copy(args_copy, args);
                rc = string_vprintf(nbuffer, remaining, &num_writ, msg, args_copy);
                va_end(args_copy);
                if( num_writ > remaining ) {
                    if(nbuffer != mbuffer) {
                        free(nbuffer);
                    }
                    nbuffer = malloc(remaining = num_writ);
                    if( nbuffer == NULL ) {
                        rc = RC(rcRuntime, rcLog, rcLogging, rcMemory, rcExhausted);
                    }
                } else {
                    if( rc == 0 ) {
                        envs[envc].name = "message";
                        envs[envc++].value = nbuffer;
                    }
                    break;
                }
            } while( rc == 0 );
        }
    }
    if( rc != 0 ) {
        /* print reason for failure */
        rc = string_printf((char*)mbuffer, sizeof(mbuffer), NULL, "status failure: %R in '%s'", rc, msg);
        envs[envc].name = "message";
        envs[envc++].value = mbuffer;
    }
    wrt_nvp_sort(envc, envs);
    rc = fmtwrt(formatter->data, writer, 0, NULL, envc, envs);
    if(nbuffer != mbuffer) {
        free(nbuffer);
    }
    return rc;
}
Exemple #2
0
static
rc_t CC LoaderXMLFormatter( void* data, KWrtHandler* writer,
                            size_t argc, const wrt_nvp_t args[],
                            size_t envc, const wrt_nvp_t envs[])

{
    rc_t rc = 0;
    size_t i, remaining, num_writ = 0;
    XMLFormatterData* self = (XMLFormatterData*)data;
    char buffer[4096];
    const char* severity, *msg_val = NULL;
    bool severity_std = false;
    char* pbuffer;
    const char* const tag_nvp_name = "severity";
    const wrt_nvp_t* msg_nvp = NULL;
    static const char* tags[] = {
        "fatal",
        "system",
        "internal",
        "error",
        "warning",
        "info"
    };

    msg_nvp = wrt_nvp_find(envc, envs, "message");
    if( msg_nvp != NULL ) {
        msg_val = msg_nvp->value;
    }
    severity = wrt_nvp_find_value(argc, args, tag_nvp_name);
    if( severity == NULL ) {
        severity = wrt_nvp_find_value(envc, envs, tag_nvp_name);
        if( severity != NULL ) {
            severity_std = true;
            /* translate std severity name to full name */
            for(i = 0; i < sizeof(tags)/sizeof(tags[0]); i++) {
                if( strncmp(severity, tags[i], strlen(severity)) == 0 ) {
                    severity = tags[i];
                    break;
                }
            }
        }
    }
    if( severity == NULL ) {
        severity = "status";
    }

#define FIX_UP() if(rc != 0){break;} remaining -= num_writ; pbuffer += num_writ
    
    pbuffer = buffer;
    remaining = sizeof(buffer);
    do {
        size_t k, pq = envc;
        const wrt_nvp_t* p = envs;
        const char* subst = NULL;

        rc = LogInsertSpace("<", pbuffer, remaining, &num_writ);
        FIX_UP();
        rc = LogInsertSpace(severity, pbuffer, remaining, &num_writ);
        FIX_UP();
        /* print env first and than args! */
        for(k = 0; rc == 0 && k < 2; k++) {
            for(i = 0; i < pq; i++ ) {
                if( strcmp(p[i].name, tag_nvp_name) == 0 ) {
                    continue;
                }
                if( p == args ) {
                    if( i == 0 && msg_nvp != NULL ) {
                        /* grab args attr buffer start */
                        subst = pbuffer;
                    }
                    if( severity_std ) {
                        /* allow only specific attributes from message into xml log
                           for LOG calls with standard severity */
                        int x, yes = 0;
                        static const char* allowed_attr[] = {
                            "file", "line", "offset",
                            "spot", "spot_name", "spotname"
                        };
                        for(x = 0; x < sizeof(allowed_attr)/sizeof(allowed_attr[0]); x++) {
                            if( strcasecmp(p[i].name, allowed_attr[x]) == 0 ) {
                                yes = 1;
                                break;
                            }
                        }
                        if( !yes ) {
                            continue;
                        }
                    }
                }
                rc = LogInsertSpace(" ", pbuffer, remaining, &num_writ);
                FIX_UP();
                rc = XMLLogger_Encode(p[i].name, pbuffer, remaining, &num_writ);
                FIX_UP();
                rc = LogInsertSpace("=\"", pbuffer, remaining, &num_writ);
                FIX_UP();
                rc = XMLLogger_Encode(p[i].value, pbuffer, remaining, &num_writ);
                FIX_UP();
                rc = LogInsertSpace("\"", pbuffer, remaining, &num_writ);
                FIX_UP();
            }
            p = args;
            pq = argc;
        }
        if( subst != NULL && subst[0] != '\0' ) {
            /* hack 'message' to print curr argv to std log as text attr="value" */
            ((wrt_nvp_t*)msg_nvp)->value = subst + 1; /* \0 terminated pre LogInsertSpace behavior */
            if( (rc = self->fmt.formatter(self->fmt.data, &self->wrt, 0, NULL, envc, envs)) != 0 ) {
                break;
            }
            ((wrt_nvp_t*)msg_nvp)->value = msg_val;
        }
        rc = LogInsertSpace("/>\n", pbuffer, remaining, &num_writ);
        FIX_UP();
    } while(false);

    if( self->file->file != NULL ) {
        if( rc != 0 ) {
            pbuffer = buffer;
            remaining = sizeof(buffer);
            rc = string_printf(pbuffer, remaining, & num_writ, "<error severity=\"err\" message=\"XML log failed: %R\"/>\n", rc);
            pbuffer += num_writ <= remaining ? num_writ : 0;
        }
        rc = KFileWrite(self->file->file, self->file->pos, buffer, pbuffer - buffer, &num_writ);
        self->file->pos += num_writ;
    }
    rc = self->fmt.formatter(self->fmt.data, &self->wrt, argc, args, envc, envs);
    return rc;
}