| | 292 | |
|---|
| | 293 | #ifdef HAVE_PROTOBUFS |
|---|
| | 294 | static int |
|---|
| | 295 | _noit_check_log_bundle_metric(noit_log_stream_t ls, Metric *metric, metric_t *m) { |
|---|
| | 296 | metric->metrictype = (int)m->metric_type; |
|---|
| | 297 | |
|---|
| | 298 | metric->name = m->metric_name; |
|---|
| | 299 | switch (m->metric_type) { |
|---|
| | 300 | case METRIC_INT32: |
|---|
| | 301 | metric->has_valuei32 = true; |
|---|
| | 302 | metric->valuei32 = *(m->metric_value.i); break; |
|---|
| | 303 | case METRIC_UINT32: |
|---|
| | 304 | metric->has_valueui32 = true; |
|---|
| | 305 | metric->valueui32 = *(m->metric_value.I); break; |
|---|
| | 306 | case METRIC_INT64: |
|---|
| | 307 | metric->has_valuei64 = true; |
|---|
| | 308 | metric->valuei64 = *(m->metric_value.l); break; |
|---|
| | 309 | case METRIC_UINT64: |
|---|
| | 310 | metric->has_valueui64 = true; |
|---|
| | 311 | metric->valueui64 = *(m->metric_value.L); break; |
|---|
| | 312 | case METRIC_DOUBLE: |
|---|
| | 313 | metric->has_valuedbl = true; |
|---|
| | 314 | metric->valuedbl = *(m->metric_value.n); break; |
|---|
| | 315 | case METRIC_STRING: |
|---|
| | 316 | metric->valuestr = m->metric_value.s; break; |
|---|
| | 317 | default: |
|---|
| | 318 | return -1; |
|---|
| | 319 | } |
|---|
| | 320 | return 0; |
|---|
| | 321 | } |
|---|
| | 322 | |
|---|
| | 323 | static int |
|---|
| | 324 | _noit_check_compress_b64(char *buf_in, |
|---|
| | 325 | uLong len_in, |
|---|
| | 326 | char ** buf_out, |
|---|
| | 327 | uLong * len_out) { |
|---|
| | 328 | uLong initial_dlen, dlen; |
|---|
| | 329 | char *compbuff, *b64buff; |
|---|
| | 330 | |
|---|
| | 331 | // Compress saves 25% of space (ex 470 -> 330) |
|---|
| | 332 | if (use_compression) { |
|---|
| | 333 | /* Compress */ |
|---|
| | 334 | initial_dlen = dlen = compressBound(len_in); |
|---|
| | 335 | compbuff = malloc(initial_dlen); |
|---|
| | 336 | if(!compbuff) return -1; |
|---|
| | 337 | if(Z_OK != compress2((Bytef *)compbuff, &dlen, |
|---|
| | 338 | (Bytef *)buf_in, len_in, 9)) { |
|---|
| | 339 | noitL(noit_error, "Error compressing bundled metrics.\n"); |
|---|
| | 340 | free(compbuff); |
|---|
| | 341 | return -1; |
|---|
| | 342 | } |
|---|
| | 343 | } else { |
|---|
| | 344 | // Or don't |
|---|
| | 345 | dlen = len_in; |
|---|
| | 346 | compbuff = buf_in; |
|---|
| | 347 | } |
|---|
| | 348 | |
|---|
| | 349 | /* Encode */ |
|---|
| | 350 | // Problems with the calculation? |
|---|
| | 351 | initial_dlen = ((dlen + 2) / 3 * 4); |
|---|
| | 352 | b64buff = malloc(initial_dlen); |
|---|
| | 353 | if (!b64buff) { |
|---|
| | 354 | if (use_compression) { |
|---|
| | 355 | // Free only if we malloc'd |
|---|
| | 356 | free(compbuff); |
|---|
| | 357 | } |
|---|
| | 358 | return -1; |
|---|
| | 359 | } |
|---|
| | 360 | dlen = noit_b64_encode((unsigned char *)compbuff, dlen, |
|---|
| | 361 | (char *)b64buff, initial_dlen); |
|---|
| | 362 | if (use_compression) { |
|---|
| | 363 | // Free only if we malloc'd |
|---|
| | 364 | free(compbuff); |
|---|
| | 365 | } |
|---|
| | 366 | if(dlen == 0) { |
|---|
| | 367 | noitL(noit_error, "Error base64'ing bundled metrics.\n"); |
|---|
| | 368 | free(b64buff); |
|---|
| | 369 | return -1; |
|---|
| | 370 | } |
|---|
| | 371 | *buf_out = b64buff; |
|---|
| | 372 | *len_out = dlen; |
|---|
| | 373 | return 0; |
|---|
| | 374 | } |
|---|
| | 375 | |
|---|
| | 376 | |
|---|
| | 377 | static int |
|---|
| | 378 | _noit_check_log_bundle_serialize(noit_log_stream_t ls, noit_check_t *check) { |
|---|
| | 379 | int rv = 0; |
|---|
| | 380 | char uuid_str[256*3+37]; |
|---|
| | 381 | noit_hash_iter iter = NOIT_HASH_ITER_ZERO; |
|---|
| | 382 | noit_hash_iter iter2 = NOIT_HASH_ITER_ZERO; |
|---|
| | 383 | const char *key; |
|---|
| | 384 | int klen, i=0, size, j; |
|---|
| | 385 | uLong out_size; |
|---|
| | 386 | stats_t *c; |
|---|
| | 387 | void *vm; |
|---|
| | 388 | char *buf, *out_buf; |
|---|
| | 389 | Bundle bundle = BUNDLE__INIT; |
|---|
| | 390 | SETUP_LOG(bundle, ); |
|---|
| | 391 | MAKE_CHECK_UUID_STR(uuid_str, sizeof(uuid_str), metrics_log, check); |
|---|
| | 392 | |
|---|
| | 393 | // Get a bundle |
|---|
| | 394 | c = &check->stats.current; |
|---|
| | 395 | |
|---|
| | 396 | // Set attributes |
|---|
| | 397 | bundle.available = c->available; |
|---|
| | 398 | bundle.state = c->state; |
|---|
| | 399 | bundle.duration = c->duration; |
|---|
| | 400 | bundle.status = c->status; |
|---|
| | 401 | |
|---|
| | 402 | |
|---|
| | 403 | // Just count |
|---|
| | 404 | while(noit_hash_next(&c->metrics, &iter, &key, &klen, &vm)) { |
|---|
| | 405 | bundle.n_metrics++; |
|---|
| | 406 | } |
|---|
| | 407 | |
|---|
| | 408 | bundle.metrics = malloc(bundle.n_metrics * sizeof(Metric*)); |
|---|
| | 409 | |
|---|
| | 410 | // Now convert |
|---|
| | 411 | while(noit_hash_next(&c->metrics, &iter2, &key, &klen, &vm)) { |
|---|
| | 412 | /* If we apply the filter set and it returns false, we don't log */ |
|---|
| | 413 | metric_t *m = (metric_t *)vm; |
|---|
| | 414 | bundle.metrics[i] = malloc(sizeof(Metric)); |
|---|
| | 415 | metric__init(bundle.metrics[i]); |
|---|
| | 416 | _noit_check_log_bundle_metric(ls, bundle.metrics[i], m); |
|---|
| | 417 | i++; |
|---|
| | 418 | } |
|---|
| | 419 | |
|---|
| | 420 | size = bundle__get_packed_size(&bundle); |
|---|
| | 421 | buf = malloc(size); |
|---|
| | 422 | bundle__pack(&bundle, (uint8_t*)buf); |
|---|
| | 423 | |
|---|
| | 424 | // Compress + B64 |
|---|
| | 425 | _noit_check_compress_b64(buf, size, &out_buf, &out_size); |
|---|
| | 426 | noit_log(ls, &(c->whence), __FILE__, __LINE__, |
|---|
| | 427 | "B\t%lu.%03lu\t%s\t%s\t%s\t%s\t%.*s\n", SECPART(&(c->whence)), MSECPART(&(c->whence)), |
|---|
| | 428 | uuid_str, check->name, check->module, check->target, |
|---|
| | 429 | (unsigned int)out_size, out_buf); |
|---|
| | 430 | |
|---|
| | 431 | free(buf); |
|---|
| | 432 | free(out_buf); |
|---|
| | 433 | // Free all the resources |
|---|
| | 434 | for (j=0; j<i; j++) { |
|---|
| | 435 | free(bundle.metrics[j]); |
|---|
| | 436 | } |
|---|
| | 437 | free(bundle.metrics); |
|---|
| | 438 | return rv; |
|---|
| | 439 | } |
|---|
| | 440 | #endif |
|---|
| | 441 | |
|---|
| | 442 | static int |
|---|
| | 443 | _noit_check_log_bundle(noit_log_stream_t ls, noit_check_t *check) { |
|---|
| | 444 | #ifdef HAVE_PROTOBUFS |
|---|
| | 445 | _noit_check_log_bundle_serialize(bundle_log, check); |
|---|
| | 446 | #else |
|---|
| | 447 | noitL(noit_error, "Trying to use bundled metrics without libprotobuf-c, recompile with support for libprotobuf-c to use bundled metrics.\n"); |
|---|
| | 448 | abort(); |
|---|
| | 449 | #endif |
|---|
| | 450 | } |
|---|
| | 451 | |
|---|
| | 452 | void |
|---|
| | 453 | noit_check_log_bundle(noit_check_t *check) { |
|---|
| | 454 | handle_extra_feeds(check, _noit_check_log_bundle); |
|---|
| | 455 | if(!(check->flags & (NP_TRANSIENT | NP_SUPPRESS_STATUS | NP_SUPPRESS_METRICS))) { |
|---|
| | 456 | SETUP_LOG(bundle, return); |
|---|
| | 457 | _noit_check_log_bundle(bundle_log, check); |
|---|
| | 458 | } |
|---|
| | 459 | } |
|---|
| | 460 | |
|---|