33 #define BUFFER_SIZE 1024
34 #define BUFFER_MAX_STRLEN (BUFFER_SIZE-2)
38 static pthread_mutex_t
BufferMutex = PTHREAD_MUTEX_INITIALIZER;
62 if (log_file == NULL) {
63 printf(
"\nLogging kinetic-c output is disabled!\n");
69 if (strncmp(log_file,
"stdout", 4) == 0 || strncmp(log_file,
"STDOUT", 4) == 0) {
71 printf(
"Logging kinetic-c output to console (stdout) w/ log_level=%d\n",
KineticLogLevel);
77 printf(
"Logging kinetic-c output to %s w/ log_level=%d\n", log_file,
KineticLogLevel);
115 if (0 == gettimeofday(&tv, NULL)) {
117 (
long long)tv.tv_sec, (
long long)tv.tv_usec);
121 va_start(arg_ptr, format);
141 if (filename == NULL || message == NULL) {
149 printf(
"\n[@%s:%d] %s\n", filename, line, message);
168 #define LOG_INDENT " "
222 const uint8_t base = 16;
231 if (c >= 10) c +=
'A' -
'0' - 10;
240 const ByteArray bytes,
const int start,
const int count)
243 for (
int i = 0; i < count; i++) {
245 len +=
bytetoa(&p_buf[len], bytes.
data[start + i]);
251 #define BOOL_TO_STRING(_bool) (_bool) ? "true" : "false"
254 void const *
const fieldData,
255 ProtobufCFieldDescriptor
const *
const fieldDesc,
259 switch (fieldDesc->type) {
260 case PROTOBUF_C_TYPE_INT32:
261 case PROTOBUF_C_TYPE_SINT32:
262 case PROTOBUF_C_TYPE_SFIXED32:
264 int32_t
const * value = (int32_t
const *)fieldData;
269 case PROTOBUF_C_TYPE_INT64:
270 case PROTOBUF_C_TYPE_SINT64:
271 case PROTOBUF_C_TYPE_SFIXED64:
273 int64_t* value = (int64_t*)fieldData;
278 case PROTOBUF_C_TYPE_UINT32:
279 case PROTOBUF_C_TYPE_FIXED32:
281 uint32_t* value = (uint32_t*)fieldData;
286 case PROTOBUF_C_TYPE_UINT64:
287 case PROTOBUF_C_TYPE_FIXED64:
289 uint64_t* value = (uint64_t*)fieldData;
294 case PROTOBUF_C_TYPE_FLOAT:
296 float* value = (
float*)fieldData;
301 case PROTOBUF_C_TYPE_DOUBLE:
303 double* value = (
double*)fieldData;
308 case PROTOBUF_C_TYPE_BOOL:
310 protobuf_c_boolean* value = (protobuf_c_boolean*)fieldData;
315 case PROTOBUF_C_TYPE_STRING:
317 char** strings = (
char**)fieldData;
322 case PROTOBUF_C_TYPE_BYTES:
324 ProtobufCBinaryData* value = (ProtobufCBinaryData*)fieldData;
328 .len = value[i].len});
333 case PROTOBUF_C_TYPE_ENUM:
335 int * value = (
int*)fieldData;
336 ProtobufCEnumDescriptor
const * enumDesc = fieldDesc->descriptor;
337 ProtobufCEnumValue
const * enumVal = protobuf_c_enum_descriptor_get_value(enumDesc, value[i]);
342 case PROTOBUF_C_TYPE_MESSAGE:
344 ProtobufCMessage** msg = (ProtobufCMessage**)fieldData;
362 if (msg == NULL || msg->descriptor == NULL || !
is_level_enabled(log_level)) {
366 ProtobufCMessageDescriptor
const * desc = msg->descriptor;
367 uint8_t
const * pMsg = (uint8_t
const *)msg;
369 for (
unsigned int i = 0; i < desc->n_fields; i++) {
370 ProtobufCFieldDescriptor
const * fieldDesc = &desc->fields[i];
372 if (fieldDesc == NULL) {
376 switch(fieldDesc->label)
378 case PROTOBUF_C_LABEL_REQUIRED:
380 LogUnboxed(log_level, &pMsg[fieldDesc->offset], fieldDesc, 0, log_indent);
382 case PROTOBUF_C_LABEL_OPTIONAL:
384 protobuf_c_boolean
const * quantifier = (protobuf_c_boolean
const *)(
void*)&pMsg[fieldDesc->quantifier_offset];
387 (PROTOBUF_C_TYPE_MESSAGE != fieldDesc->type || ((ProtobufCMessage**)(
void*)&pMsg[fieldDesc->offset])[0] != NULL))
390 if ((protobuf_c_message_descriptor_get_field_by_name(desc,
"commandBytes") == fieldDesc ) &&
391 (PROTOBUF_C_TYPE_BYTES == fieldDesc->type))
393 ProtobufCBinaryData* value = (ProtobufCBinaryData*)(
void*)&pMsg[fieldDesc->offset];
394 if ((value->data != NULL) && (value->len > 0)) {
403 LogUnboxed(log_level, &pMsg[fieldDesc->offset], fieldDesc, 0, log_indent);
407 case PROTOBUF_C_LABEL_REPEATED:
409 unsigned const * quantifier = (
unsigned const *)(
void*)&pMsg[fieldDesc->quantifier_offset];
410 if (*quantifier > 0) {
412 for (uint32_t j = 0; j < *quantifier; j++) {
413 void const ** box = (
void const **)(
void*)&pMsg[fieldDesc->offset];
414 LogUnboxed(log_level, *box, fieldDesc, j, log_indent);
441 ProtobufCMessage* protoMessage = &status->base;
452 const ProtobufCMessageDescriptor* protoMessageDescriptor = protoMessage->descriptor;
453 const ProtobufCFieldDescriptor* statusCodeDescriptor =
454 protobuf_c_message_descriptor_get_field_by_name(protoMessageDescriptor,
"code");
455 const ProtobufCEnumDescriptor* statusCodeEnumDescriptor =
456 (ProtobufCEnumDescriptor*)statusCodeDescriptor->descriptor;
457 const ProtobufCEnumValue* eStatusCodeVal =
458 protobuf_c_enum_descriptor_get_value(statusCodeEnumDescriptor, code);
460 statusCodeDescriptor->name, code, eStatusCodeVal->name);
463 if (status->statusmessage) {
464 const ProtobufCFieldDescriptor* statusMsgFieldDescriptor =
465 protobuf_c_message_descriptor_get_field_by_name(protoMessageDescriptor,
"statusMessage");
466 const ProtobufCMessageDescriptor* statusMsgDescriptor =
467 (ProtobufCMessageDescriptor*)statusMsgFieldDescriptor->descriptor;
473 if (status->has_detailedmessage) {
474 char tmp[8], msg[256];
475 const ProtobufCFieldDescriptor* statusDetailedMsgFieldDescriptor =
476 protobuf_c_message_descriptor_get_field_by_name(
477 protoMessageDescriptor,
"detailedMessage");
478 const ProtobufCMessageDescriptor* statusDetailedMsgDescriptor =
479 (ProtobufCMessageDescriptor*)
480 statusDetailedMsgFieldDescriptor->descriptor;
482 sprintf(msg,
" %s: ", statusDetailedMsgDescriptor->name);
483 for (
size_t i = 0; i < status->detailedmessage.len; i++) {
484 sprintf(tmp,
"%02hhX", status->detailedmessage.data[i]);
498 if (bytes.
data == NULL) {
502 if (bytes.
data == NULL) {
507 const int byteChars = 4;
508 const int bytesPerLine = 32;
509 const int lineLen = 4 + (bytesPerLine * byteChars);
510 char hex[lineLen + 1];
511 char ascii[lineLen + 1];
512 for (
size_t i = 0; i < bytes.
len;) {
516 j < bytesPerLine && i < bytes.
len;
519 sprintf(byHex,
"%02hhX", bytes.
data[i]);
522 int ch = (int)bytes.
data[i];
523 if (ch >= 32 && ch <= 126) {
524 sprintf(byAscii,
"%c", bytes.
data[i]);
530 strcat(ascii, byAscii);
550 return (log_level <= KineticLogLevel && KineticLogLevel >= 0);
#define KINETIC_C_VERSION
Structure for handling generic arrays of bytes.
void KineticLogger_LogHeader(int log_level, const KineticPDUHeader *header)
static void flush_buffer(void)
Structure for an embedded ByteArray as a buffer.
void KineticLogger_LogStatus(int log_level, Com__Seagate__Kinetic__Proto__Command__Status *status)
static void unlock_buffer(void)
static int indent_overflow
static FILE * KineticLoggerHandle
static int KineticLogLevel
static void log_proto_level_start_array(const char *name, unsigned quantity)
static void log_version_info(void)
Com__Seagate__Kinetic__Proto__Command * com__seagate__kinetic__proto__command__unpack(ProtobufCAllocator *allocator, size_t len, const uint8_t *data)
ByteArray array
ByteArray holding allocated array w/length = allocated size.
int KineticLogger_ByteArraySliceToCString(char *p_buf, const ByteArray bytes, const int start, const int count)
static void lock_buffer(void)
#define BOOL_TO_STRING(_bool)
static void log_proto_level_start(const char *name)
#define KINETIC_ASSERT(cond)
void KineticLogger_LogByteBuffer(int log_level, const char *title, ByteBuffer buffer)
static int bytetoa(char *p_buf, uint8_t val)
void KineticLogger_LogLocation(const char *filename, int line, const char *message)
static void log_proto_level_end_array(void)
size_t len
Number of bytes in the data field.
static void LogUnboxed(int log_level, void const *const fieldData, ProtobufCFieldDescriptor const *const fieldDesc, size_t const i, char *log_indent)
static const size_t max_indent
#define BUFFER_MAX_STRLEN
uint8_t * data
Pointer to an allocated array of data bytes.
static char * get_buffer(void)
void KineticLogger_LogProtobuf(int log_level, const Com__Seagate__Kinetic__Proto__Message *msg)
#define KINETIC_C_REPO_HASH
void KineticLogger_LogByteArray(int log_level, const char *title, ByteArray bytes)
static void finish_buffer(void)
void KineticLogger_Close(void)
void KineticLogger_LogPrintf(int log_level, const char *format,...)
#define KINETIC_C_PROTOCOL_VERSION
size_t bytesUsed
Reflects the number of bytes used from the array
static void log_proto_level_end(void)
Com__Seagate__Kinetic__Proto__Command__Status__StatusCode
void KineticLogger_Log(int log_level, const char *message)
static pthread_mutex_t BufferMutex
void com__seagate__kinetic__proto__command__free_unpacked(Com__Seagate__Kinetic__Proto__Command *message, ProtobufCAllocator *allocator)
static bool is_level_enabled(int log_level)
void KineticLogger_Init(const char *log_file, int log_level)
static void log_protobuf_message(int log_level, const ProtobufCMessage *msg, char *indent)