예제 #1
0
파일: nc_log.c 프로젝트: idning/ndb
void
_log(int level, const char *file, int line, int panic, const char *fmt, ...)
{
    struct logger *l = &logger;
    int len, size, errno_save;
    char buf[LOG_MAX_LEN];
    va_list args;
    ssize_t n;
    struct timeval tv;

    if (l->fd < 0) {
        return;
    }

    errno_save = errno;
    len = 0;            /* length of output buffer */
    size = LOG_MAX_LEN; /* size of output buffer */

    gettimeofday(&tv, NULL);
    buf[len++] = '[';
    len += (int)strftime(buf + len, (size_t)(size - len), "%Y-%m-%d %H:%M:%S.", localtime(&tv.tv_sec));
    len += nc_scnprintf(buf + len, size - len, "%03d", (int)tv.tv_usec/1000);
    len += nc_scnprintf(buf + len, size - len, "] %6s [%"PRIu64"] ", log_level_s(level), gettid());
    len += nc_scnprintf(buf + len, size - len, "%s:%d ", file, line);

    va_start(args, fmt);
    len += nc_vscnprintf(buf + len, size - len, fmt, args);
    va_end(args);

    buf[len++] = '\n';

    n = nc_write(l->fd, buf, len);
    if (n < 0) {
        l->nerror++;
    }

    errno = errno_save;

    if (panic) {
        abort();
    }
}
예제 #2
0
파일: nc_misc.c 프로젝트: idning/ndb
/*
 * Unresolve the socket address by translating it to a character string
 * describing the host and service
 *
 * This routine is not reentrant
 */
char *
nc_unresolve_addr(struct sockaddr *addr, socklen_t addrlen)
{
    static char unresolve[NI_MAXHOST + NI_MAXSERV];
    static char host[NI_MAXHOST], service[NI_MAXSERV];
    int status;

    status = getnameinfo(addr, addrlen, host, sizeof(host),
                         service, sizeof(service),
                         NI_NUMERICHOST | NI_NUMERICSERV);
    if (status < 0) {
        return "unknown";
    }

    nc_scnprintf(unresolve, sizeof(unresolve), "%s:%s", host, service);

    return unresolve;
}
예제 #3
0
/* Create a new slowlog entry.
 * Incrementing the ref count of all the objects retained is up to
 * this function. */
static slowlog_entry *slowlog_create_entry(struct msg *r, long long duration) {
    slowlog_entry *se = nc_alloc(sizeof(*se));
    uint32_t j, keys_count, keys_count_input;

    se->cmdtype = r->type;

    keys_count_input = keys_count = r->keys==NULL?0:array_n(r->keys);

    if (keys_count_input > SLOWLOG_ENTRY_MAX_KEYS) keys_count_input = SLOWLOG_ENTRY_MAX_KEYS;
    se->keys_count = (int)keys_count;
    if (keys_count_input > 0) {
        se->keys = array_create(keys_count_input, sizeof(struct string));
        for (j = 0; j < keys_count_input; j ++) {
            struct keypos *kp = array_get(r->keys, j);
            struct string *key = array_push(se->keys);
            uint32_t key_len = (uint32_t)(kp->end-kp->start);
            string_init(key);
            if (key_len > SLOWLOG_ENTRY_MAX_STRING) {
                int len;
                uint8_t buf[SLOWLOG_ENTRY_MAX_STRING+50];
                memcpy(buf,kp->start,SLOWLOG_ENTRY_MAX_STRING);
                len = nc_scnprintf(buf+SLOWLOG_ENTRY_MAX_STRING,
                    50,"... (%lu more bytes)",
                    key_len-SLOWLOG_ENTRY_MAX_STRING);            
                if (len > 0) {
                    string_copy(key,buf,SLOWLOG_ENTRY_MAX_STRING+(uint32_t)len);
                } else {
                    string_copy(key,kp->start,SLOWLOG_ENTRY_MAX_STRING);
                }
            } else {
                string_copy(key,kp->start,key_len);
            }
        }
    }else {
        se->keys = NULL;
    }
    
    se->time = time(NULL);
    se->duration = duration;

    STAILQ_NEXT(se, next) = NULL;
    
    return se;
}
예제 #4
0
struct msg *
memcache_generate_error(struct msg *r, err_t err)
{
    struct mbuf *mbuf;
    int n;
    char *protstr = "SERVER_ERROR";
    char *errstr = err ? strerror(err) : "unknown";

    r->type = MSG_RSP_MC_SERVER_ERROR;

    mbuf = mbuf_get();
    if (mbuf == NULL) {
        return NULL;
    }
    mbuf_insert(&r->mhdr, mbuf);

    n = nc_scnprintf(mbuf->last, mbuf_size(mbuf), "%s %s"CRLF, protstr, errstr);
    mbuf->last += n;
    r->mlen = (uint32_t)n;

    return r;
}
예제 #5
0
rstatus_t
slowlog_command_make_reply(struct context *ctx, 
	struct conn *conn, struct msg *msg, struct msg *pmsg)
{
	rstatus_t status;
	uint32_t nkeys;
	struct keypos *kp;
	char *contents;
    uint32_t subcmdlen;
	
	ASSERT(conn->client && !conn->proxy);
    ASSERT(msg->request);
	ASSERT(pmsg != NULL && !pmsg->request);
    ASSERT(msg->owner == conn);
	ASSERT(conn->owner == ctx->manager);

	nkeys = array_n(msg->keys);
	ASSERT(nkeys >= 1);

	kp = array_get(msg->keys, 0);
    subcmdlen = (uint32_t)(kp->end-kp->start);
    if (subcmdlen==strlen("reset")&&!memcmp(kp->start,"reset",subcmdlen)){
        if (nkeys != 1) {
            goto format_error;
        }
        
        slowlog_reset();
        status = msg_append_full(pmsg, (uint8_t*)"OK", 2);
        if (status != NC_OK) {
    		conn->err = ENOMEM;
            return status;
        }
        
        goto done;
    } else if (subcmdlen==strlen("id")&&!memcmp(kp->start,"id",subcmdlen)){
        int buf_len;
        uint8_t buf[30];
        long long id;

        if (nkeys != 1) {
            goto format_error;
        }

        pthread_rwlock_rdlock(&rwlocker);
        id = slowlog_entry_id;
        pthread_rwlock_unlock(&rwlocker);
        
        buf_len = nc_scnprintf(buf,30,"%lld",id);
        status = msg_append_full(pmsg, buf, (size_t)buf_len);
        if (status != NC_OK) {
    		conn->err = ENOMEM;
            return status;
        }
        goto done;
    } else if (subcmdlen==strlen("len")&&!memcmp(kp->start,"len",subcmdlen)){
        int len, buf_len;
        uint8_t buf[20];

        if (nkeys != 1) {
            goto format_error;
        }

        pthread_rwlock_rdlock(&rwlocker);
        len = slowlog_len;
        pthread_rwlock_unlock(&rwlocker);
        
        buf_len = nc_scnprintf(buf,20,"%d",len);
        status = msg_append_full(pmsg, buf, (size_t)buf_len);
        if (status != NC_OK) {
    		conn->err = ENOMEM;
            return status;
        }
        goto done;
    } else if (subcmdlen==strlen("get")&&!memcmp(kp->start,"get",subcmdlen)){
        int count, sent = 0, buf_len;
        uint8_t buf[50];
        slowlog_entry *se;
        struct string *str;
        
        if (nkeys == 1) {
            count = 10;
        } else if (nkeys == 2) {
            kp = array_get(msg->keys, 1);
            count = nc_atoi(kp->start, (kp->end-kp->start));
            if (count < 0) {
                goto format_error;
            }
        } else {
            goto format_error;
        }

        pthread_rwlock_rdlock(&rwlocker);
        se = STAILQ_FIRST(&slowlog);
        while(count-- && se != NULL) {
            int nfield;
            uint32_t j;            

            sent++;
            buf_len = nc_scnprintf(buf,50,"%d) 1) %lld\r\n",sent, se->id);
            status = msg_append_full(pmsg, buf, (size_t)buf_len);
            if (status != NC_OK) {
                pthread_rwlock_unlock(&rwlocker);
        		conn->err = ENOMEM;
                return status;
            }
            buf_len = nc_scnprintf(buf,50,"    2) %lld\r\n",se->time);
            status = msg_append_full(pmsg, buf, (size_t)buf_len);
            if (status != NC_OK) {
                pthread_rwlock_unlock(&rwlocker);
        		conn->err = ENOMEM;
                return status;
            }
            buf_len = nc_scnprintf(buf,50,"    3) %lld\r\n",se->duration);
            status = msg_append_full(pmsg, buf, (size_t)buf_len);
            if (status != NC_OK) {
                pthread_rwlock_unlock(&rwlocker);
        		conn->err = ENOMEM;
                return status;
            }
            str = msg_type_string(se->cmdtype);
            nfield = 1;
            buf_len = nc_scnprintf(buf,50,"    4) %d) %s\r\n",nfield++,str->data);
            status = msg_append_full(pmsg, buf, (size_t)buf_len);
            if (status != NC_OK) {
                pthread_rwlock_unlock(&rwlocker);
        		conn->err = ENOMEM;
                return status;
            }
            buf_len = nc_scnprintf(buf,50,"       %d) %d\r\n",nfield++,se->keys_count);
            status = msg_append_full(pmsg, buf, (size_t)buf_len);
            if (status != NC_OK) {
                pthread_rwlock_unlock(&rwlocker);
        		conn->err = ENOMEM;
                return status;
            }
            if (se->keys != NULL) {
                for (j = 0; j < array_n(se->keys); j ++) {
                    str = array_get(se->keys, j);
                    
                    buf_len = nc_scnprintf(buf,50,"       %d) ",nfield++);
                    status = msg_append_full(pmsg, buf, (size_t)buf_len);
                    if (status != NC_OK) {
                        pthread_rwlock_unlock(&rwlocker);
                		conn->err = ENOMEM;
                        return status;
                    }
                    status = msg_append_full(pmsg, str->data, (size_t)str->len);
                    if (status != NC_OK) {
                        pthread_rwlock_unlock(&rwlocker);
                		conn->err = ENOMEM;
                        return status;
                    }
                    status = msg_append_full(pmsg, (uint8_t *)CRLF, CRLF_LEN);
                    if (status != NC_OK) {
                        pthread_rwlock_unlock(&rwlocker);
                		conn->err = ENOMEM;
                        return status;
                    }
                }
            }
            se = STAILQ_NEXT(se, next);
        }
        pthread_rwlock_unlock(&rwlocker);
        
        if (msg_empty(pmsg)) {
            status = msg_append_full(pmsg, (uint8_t*)"END", 3);
            if (status != NC_OK) {
        		conn->err = ENOMEM;
                return status;
            }
            goto done;
        }
        return NC_OK;
    } else if (subcmdlen==strlen("overview") &&
        !memcmp(kp->start,"overview",subcmdlen)) {
        int count, buf_len;
        uint8_t buf[50];
        int j, idx, id;
        struct statistics_oneday *so;
        
        if (nkeys == 1) {
            count = 10;
        } else if (nkeys == 2) {
            kp = array_get(msg->keys, 1);
            count = nc_atoi(kp->start, (kp->end-kp->start));
            if (count < 0) {
                goto format_error;
            }
        } else {
            goto format_error;
        }

        if (slowlog_statistics == NULL) {
            status = msg_append_full(pmsg, (uint8_t*)"END", 3);
            if (status != NC_OK) {
        		conn->err = ENOMEM;
                return status;
            }
            goto done;
        }

        if (count > statistics_days)
            count = statistics_days;
        pthread_mutex_lock(&statistics_locker);
        idx = today_idx;
        id = 1;
        while (count--) {
            so = &slowlog_statistics[idx];

            if (so->year == 0)
                break;

            buf_len = nc_scnprintf(buf,50,"%d) %d-%d-%d ",id++,so->year+1900,so->mon+1,so->day);
            status = msg_append_full(pmsg, buf, (size_t)buf_len);
            if (status != NC_OK) {
                pthread_mutex_unlock(&statistics_locker);
        		conn->err = ENOMEM;
                return status;
            }

            for (j = 0; j < statistics_period-1; j ++) {
                buf_len = nc_scnprintf(buf,50,"%lld ",so->periods[j]);
                status = msg_append_full(pmsg, buf, (size_t)buf_len);
                if (status != NC_OK) {
                    pthread_mutex_unlock(&statistics_locker);
            		conn->err = ENOMEM;
                    return status;
                }
            }
            buf_len = nc_scnprintf(buf,50,"%lld\r\n",so->periods[statistics_period-1]);
            status = msg_append_full(pmsg, buf, (size_t)buf_len);
            if (status != NC_OK) {
                pthread_mutex_unlock(&statistics_locker);
        		conn->err = ENOMEM;
                return status;
            }
            
            if (--idx < 0) {
                idx = statistics_days - 1;
            }
        }
        pthread_mutex_unlock(&statistics_locker);

        if (msg_empty(pmsg)) {
            status = msg_append_full(pmsg, (uint8_t*)"END", 3);
            if (status != NC_OK) {
        		conn->err = ENOMEM;
                return status;
            }
            goto done;
        }
        return NC_OK;
    } else {
        goto format_error;
    }

format_error:
    contents = "ERR: slowlog command format is error.";
    status = msg_append_full(pmsg, (uint8_t *)contents, strlen(contents));
    if (status != NC_OK) {
		conn->err = ENOMEM;
        return status;
    }
    
    goto done;
done:
    status = msg_append_full(pmsg, (uint8_t *)CRLF, CRLF_LEN);
    if (status != NC_OK) {
		conn->err = ENOMEM;
        return status;
    }
	return NC_OK;
}
예제 #6
0
파일: nc_log.c 프로젝트: idning/ndb
/*
 * Hexadecimal dump in the canonical hex + ascii display
 * See -C option in man hexdump
 */
void
_log_hexdump(const char *file, int line, char *data, int datalen,
             const char *fmt, ...)
{
    struct logger *l = &logger;
    char buf[8 * LOG_MAX_LEN];
    int i, off, len, size, errno_save;
    ssize_t n;

    if (l->fd < 0) {
        return;
    }

    /* log hexdump */
    errno_save = errno;
    off = 0;                  /* data offset */
    len = 0;                  /* length of output buffer */
    size = 8 * LOG_MAX_LEN;   /* size of output buffer */

    while (datalen != 0 && (len < size - 1)) {
        char *save, *str;
        unsigned char c;
        int savelen;

        len += nc_scnprintf(buf + len, size - len, "%08x  ", off);

        save = data;
        savelen = datalen;

        for (i = 0; datalen != 0 && i < 16; data++, datalen--, i++) {
            c = (unsigned char)(*data);
            str = (i == 7) ? "  " : " ";
            len += nc_scnprintf(buf + len, size - len, "%02x%s", c, str);
        }
        for ( ; i < 16; i++) {
            str = (i == 7) ? "  " : " ";
            len += nc_scnprintf(buf + len, size - len, "  %s", str);
        }

        data = save;
        datalen = savelen;

        len += nc_scnprintf(buf + len, size - len, "  |");

        for (i = 0; datalen != 0 && i < 16; data++, datalen--, i++) {
            c = (unsigned char)(isprint(*data) ? *data : '.');
            len += nc_scnprintf(buf + len, size - len, "%c", c);
        }
        len += nc_scnprintf(buf + len, size - len, "|\n");

        off += 16;
    }

    n = nc_write(l->fd, buf, len);
    if (n < 0) {
        l->nerror++;
    }

    if (len >= size - 1) {
        n = nc_write(l->fd, "\n", 1);
        if (n < 0) {
            l->nerror++;
        }
    }

    errno = errno_save;
}