Example #1
0
static
rc_t CC KStsDefaultFormatter( void* self, KWrtHandler* writer,
                              size_t argc, const wrt_nvp_t args[],
                              size_t envc, const wrt_nvp_t envs[] )
{
    rc_t rc = 0;
    size_t num_writ, nsize;
    uint32_t mlen;
    char buffer[8192], *nbuffer;
    const char* msg, *mend;

    /* if writer is null than silence */
    if( writer == NULL || writer->writer == NULL ) {
        return rc;
    }
    msg = wrt_nvp_find_value(envc, envs, "message");
    if( msg != NULL ) {
        mend = msg + strlen(msg);
        /* strip trailing newlines */
        while( mend != msg && (*mend == '\n' || *mend == '\r') ) {
            --mend;
        }
        mlen = ( uint32_t ) ( mend - msg );
    } else {
        mlen = 0;
    }

    nbuffer = buffer;
    nsize = sizeof(buffer);
    do {
        rc = string_printf(nbuffer, nsize, & num_writ, "%s %s.%s: %.*s\n",
                                 wrt_nvp_find_value(envc, envs, "timestamp"),
                                 wrt_nvp_find_value(envc, envs, "app"),
                                 wrt_nvp_find_value(envc, envs, "version"),
                                 ( uint32_t ) mlen, msg);
        if( num_writ > nsize ) {
            assert ( nbuffer == buffer );
            nbuffer = malloc(nsize = num_writ + 2);
            if( nbuffer == NULL ) {
                rc = RC(rcRuntime, rcLog, rcLogging, rcMemory, rcExhausted);
                break;
            }
            continue;
        }
        /* replace newlines with spaces, excluding last one */
        for(nsize = 0; nsize < num_writ - 1; nsize++) {
            if( nbuffer[nsize] == '\n' || nbuffer[nsize] == '\r' ) {
                nbuffer[nsize] = ' ';
            }
        }
        break;
    } while(true);
    if( rc == 0 ) {
        rc = LogFlush(writer, nbuffer, num_writ);
    }
    if( nbuffer != buffer ) {
        free(nbuffer);
    }
    return rc;
}
Example #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;
}