int main(int argc, char *argv[]) {
  int r;
  sd_journal *j;
  r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
  if (r < 0) {
    fprintf(stderr, "Failed to open journal: %s\n", strerror(-r));
    return 1;
  }
  for (;;)  {
    const void *d;
    size_t l;
    r = sd_journal_next(j);
    if (r < 0) {
      fprintf(stderr, "Failed to iterate to next entry: %s\n", strerror(-r));
      break;
    }
    if (r == 0) {
      /* Reached the end, let's wait for changes, and try again */
      r = sd_journal_wait(j, (uint64_t) -1);
      if (r < 0) {
        fprintf(stderr, "Failed to wait for changes: %s\n", strerror(-r));
        break;
      }
      continue;
    }
    r = sd_journal_get_data(j, "MESSAGE", &d, &l);
    if (r < 0) {
      fprintf(stderr, "Failed to read message field: %s\n", strerror(-r));
      continue;
    }
    printf("%.*s\n", (int) l, (const char*) d);
  }
  sd_journal_close(j);
  return 0;
}
示例#2
0
int main(int argc, char *argv[]) {
        unsigned n = 0;
        _cleanup_journal_close_ sd_journal*j = NULL;

        log_set_max_level(LOG_DEBUG);

        assert_se(sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY) >= 0);

        assert_se(sd_journal_add_match(j, "_TRANSPORT=syslog", 0) >= 0);
        assert_se(sd_journal_add_match(j, "_UID=0", 0) >= 0);

        SD_JOURNAL_FOREACH_BACKWARDS(j) {
                const void *d;
                size_t l;

                assert_se(sd_journal_get_data(j, "MESSAGE", &d, &l) >= 0);

                printf("%.*s\n", (int) l, (char*) d);

                n ++;
                if (n >= 10)
                        break;
        }

        return 0;
}
示例#3
0
static void verify_contents(sd_journal *j, unsigned skip) {
        unsigned i;

        assert(j);

        i = 0;
        SD_JOURNAL_FOREACH(j) {
                const void *d;
                char *k, *c;
                size_t l;
                unsigned u;

                assert_se(sd_journal_get_cursor(j, &k) >= 0);
                printf("cursor: %s\n", k);
                free(k);

                assert_se(sd_journal_get_data(j, "MAGIC", &d, &l) >= 0);
                printf("\t%.*s\n", (int) l, (const char*) d);

                assert_se(sd_journal_get_data(j, "NUMBER", &d, &l) >= 0);
                assert_se(k = strndup(d, l));
                printf("\t%s\n", k);

                if (skip > 0) {
                        assert_se(safe_atou(k + 7, &u) >= 0);
                        assert_se(i == u);
                        i += skip;
                }

                free(k);

                assert_se(sd_journal_get_cursor(j, &c) >= 0);
                assert_se(sd_journal_test_cursor(j, c) > 0);
                free(c);
        }

        if (skip > 0)
                assert_se(i == N_ENTRIES);
}
static void test_check_number (sd_journal *j, int n) {
        const void *d;
        _cleanup_free_ char *k;
        size_t l;
        int x;

        assert_ret(sd_journal_get_data(j, "NUMBER", &d, &l));
        assert_se(k = strndup(d, l));
        printf("%s\n", k);

        assert_se(safe_atoi(k + 7, &x) >= 0);
        assert_se(n == x);
}
示例#5
0
文件: systemd.c 项目: Aconex/pcp
/* Return a strndup (or NULL) of a field of the current journal entry,
   since sd_journal_get_data returns data that is not
   \0-terminated. */
char *
my_sd_journal_get_data(sd_journal *j, const char *field)
{
    int rc;
    const char* str;
    size_t str_len;

    assert (j != NULL);
    assert (field != NULL);

    rc = sd_journal_get_data(j, field,
                             (const void**) & str, & str_len);
    if (rc < 0)
        return NULL;

    return strndup (str, str_len);
}
示例#6
0
static int journal_get_data (lua_State *L) {
	sd_journal *j = check_journal(L, 1);
	const char *field = luaL_checkstring(L, 2);
	const void *data;
	size_t length;
	int err = sd_journal_get_data(j, field, &data, &length);
	if (err == -ENOENT) {
		lua_pushboolean(L, 0);
		lua_pushnil(L);
		return 2;
	} else if (err != 0) {
		return handle_error(L, -err);
	} else {
		lua_pushboolean(L, 1);
		lua_pushlstring(L, data, length);
		return 2;
	}
}
示例#7
0
int main(int argc, char *argv[]) {
        JournalFile *one, *two, *three;
        char t[] = "/tmp/journal-stream-XXXXXX";
        unsigned i;
        _cleanup_journal_close_ sd_journal *j = NULL;
        char *z;
        const void *data;
        size_t l;

        log_set_max_level(LOG_DEBUG);

        assert_se(mkdtemp(t));
        assert_se(chdir(t) >= 0);

        assert_se(journal_file_open("one.journal", O_RDWR|O_CREAT, 0666, true, NULL, NULL, NULL, &one) == 0);
        assert_se(journal_file_open("two.journal", O_RDWR|O_CREAT, 0666, true, NULL, NULL, NULL, &two) == 0);
        assert_se(journal_file_open("three.journal", O_RDWR|O_CREAT, 0666, true, NULL, NULL, NULL, &three) == 0);

        for (i = 0; i < N_ENTRIES; i++) {
                char *p, *q;
                dual_timestamp ts;
                struct iovec iovec[2];

                dual_timestamp_get(&ts);

                assert_se(asprintf(&p, "NUMBER=%u", i) >= 0);
                iovec[0].iov_base = p;
                iovec[0].iov_len = strlen(p);

                assert_se(asprintf(&q, "MAGIC=%s", i % 5 == 0 ? "quux" : "waldo") >= 0);

                iovec[1].iov_base = q;
                iovec[1].iov_len = strlen(q);

                if (i % 10 == 0)
                        assert_se(journal_file_append_entry(three, &ts, iovec, 2, NULL, NULL, NULL) == 0);
                else {
                        if (i % 3 == 0)
                                assert_se(journal_file_append_entry(two, &ts, iovec, 2, NULL, NULL, NULL) == 0);

                        assert_se(journal_file_append_entry(one, &ts, iovec, 2, NULL, NULL, NULL) == 0);
                }

                free(p);
                free(q);
        }

        journal_file_close(one);
        journal_file_close(two);
        journal_file_close(three);

        assert_se(sd_journal_open_directory(&j, t, 0) >= 0);

        assert_se(sd_journal_add_match(j, "MAGIC=quux", 0) >= 0);
        SD_JOURNAL_FOREACH_BACKWARDS(j) {
                _cleanup_free_ char *c = NULL;

                assert_se(sd_journal_get_data(j, "NUMBER", &data, &l) >= 0);
                printf("\t%.*s\n", (int) l, (const char*) data);

                assert_se(sd_journal_get_cursor(j, &c) >= 0);
                assert_se(sd_journal_test_cursor(j, c) > 0);
        }

        SD_JOURNAL_FOREACH(j) {
                _cleanup_free_ char *c = NULL;

                assert_se(sd_journal_get_data(j, "NUMBER", &data, &l) >= 0);
                printf("\t%.*s\n", (int) l, (const char*) data);

                assert_se(sd_journal_get_cursor(j, &c) >= 0);
                assert_se(sd_journal_test_cursor(j, c) > 0);
        }

        sd_journal_flush_matches(j);

        verify_contents(j, 1);

        printf("NEXT TEST\n");
        assert_se(sd_journal_add_match(j, "MAGIC=quux", 0) >= 0);

        assert_se(z = journal_make_match_string(j));
        printf("resulting match expression is: %s\n", z);
        free(z);

        verify_contents(j, 5);

        printf("NEXT TEST\n");
        sd_journal_flush_matches(j);
        assert_se(sd_journal_add_match(j, "MAGIC=waldo", 0) >= 0);
        assert_se(sd_journal_add_match(j, "NUMBER=10", 0) >= 0);
        assert_se(sd_journal_add_match(j, "NUMBER=11", 0) >= 0);
        assert_se(sd_journal_add_match(j, "NUMBER=12", 0) >= 0);

        assert_se(z = journal_make_match_string(j));
        printf("resulting match expression is: %s\n", z);
        free(z);

        verify_contents(j, 0);

        assert_se(sd_journal_query_unique(j, "NUMBER") >= 0);
        SD_JOURNAL_FOREACH_UNIQUE(j, data, l)
                printf("%.*s\n", (int) l, (const char*) data);

        assert_se(rm_rf_dangerous(t, false, true, false) >= 0);

        return 0;
}
char *get_entry_string(){
    const void *data;
    json_t *message = json_object();
    size_t length;

    // journal meta information, prefixed by '__'
    char *cursor;
    uint64_t realtime_usec;
    uint64_t monotonic_usec;
    sd_id128_t boot_id;

    /* mapping from systemd- to GELF- field names */
    const char *fn_sd_host="_HOSTNAME", *fn_gelf_host="host";
    const char *fn_sd_msg="MESSAGE",    *fn_gelf_msg="short_message";
    const char /**fn_sd_time="__REALTIME_TIMESTAMP",*/ *fn_gelf_time="timestamp";
    const char *fn_sd_prio="PRIORITY",  *fn_gelf_prio="level";

    int rc = 0;

    //add version field necessary for GELF
    json_object_set_new(message, "version", json_string("1.1"));

    /* get data necessary for GELF*/

    rc = sd_journal_get_data(j, fn_sd_host, &data, &length);
    if (!rc){
        char *v = get_value(data, length);
	    assert(v);
        json_object_set_new(message, fn_gelf_host, json_string(v));
        free(v);
    }
    else{
        json_object_set_new(message, fn_gelf_host, json_string("not_available"));
    }
    rc = sd_journal_get_data(j, fn_sd_msg, &data, &length);
    if (!rc){
        char *v = get_value(data, length);
        assert(v);
        json_object_set_new(message, fn_gelf_msg, json_string(v));
        free(v);
    }
    else{
        json_object_set_new(message, fn_gelf_msg, json_string("not_available"));
    }
    rc = sd_journal_get_data(j, fn_sd_prio, &data, &length);
    if (!rc){
        char *v = get_value(data, length);
        assert(v);
        int prio = strtol(v, NULL, 10);
        if (prio<0) prio = 0;
        if (prio>7) prio = 7;
        //TODO: log meldung absetzen
        json_object_set_new(message, fn_gelf_prio, json_integer(prio));
        free(v);
    }
    else{
        json_object_set_new(message, fn_gelf_prio, json_string("not_available"));
    }

    // get systemd journal meta fields cursor, realtime- and monotonic timestamp
    // __REALTIME_TIMESTAMP corresponds to  GELF necessary timestamp
    const char *meta_prefixes[] = {"___CURSOR", fn_gelf_time , "___MONOTONIC_TIMESTAMP" };
    sd_journal_get_cursor( j, &cursor );    // needs to be free'd afterwards
    json_object_set_new(message, meta_prefixes[0], json_string(cursor));
    free(cursor);

    sd_journal_get_realtime_usec( j, &realtime_usec );
    json_object_set_new(message, meta_prefixes[1], json_integer(realtime_usec));

    sd_journal_get_monotonic_usec( j, &monotonic_usec, &boot_id);
    json_object_set_new(message, meta_prefixes[2], json_integer(monotonic_usec));

    /* get all remaining fields */
    // (PRIORITY, _HOSTNAME, and MESSAGE are read again)

    // format of prefixes: additional '_' for additional fields in GELF
    // format of retrieved arguments: data="FIELD_NAME=field_value" length=
    SD_JOURNAL_FOREACH_DATA(j, data, length){
        char *v = get_value(data, length);
        assert(v);
        char *k = get_key(data);
        assert(k);
        json_object_set_new(message, k, json_string(v));
        free(v);
        free(k);
    }
示例#9
0
/* Read journal log while data are available, each read() reads one
 * record of printk buffer.
 */
static rsRetVal
readjournal() {
	DEFiRet;

	struct timeval tv;
	uint64_t timestamp;

	struct json_object *json = NULL;
	int r;

	/* Information from messages */
	char *message;
	char *sys_pid;
	char *sys_iden;
	char *sys_iden_help;

	const void *get;
	const void *pidget;
	char *parse;
	size_t length;
	size_t pidlength;

	const void *equal_sign;
	struct json_object *jval;
	char *data;
	char *name;
	size_t l;

	long prefixlen = 0;

	int severity = cs.iDfltSeverity;
	int facility = cs.iDfltFacility;

	/* Get message text */
	if (sd_journal_get_data(j, "MESSAGE", &get, &length) < 0) {
		message = strdup("");
	} else {
		message = strndup(((const char*)get)+8, length-8);
		if (message == NULL) {
			iRet = RS_RET_OUT_OF_MEMORY;
			goto ret;
		}
	}

	/* Get message severity ("priority" in journald's terminology) */
	if (sd_journal_get_data(j, "PRIORITY", &get, &length) >= 0) {
		if (length == 10) {
			severity = ((char *)get)[9] - '0';
			if (severity < 0 || 7 < severity) {
				dbgprintf("The value of the 'PRIORITY' field is "
					"out of bounds: %d, resetting\n", severity);
				severity = cs.iDfltSeverity;
			}
		} else {
			dbgprintf("The value of the 'PRIORITY' field has an "
				"unexpected length: %d\n", length);
		}
	}

	/* Get syslog facility */
	if (sd_journal_get_data(j, "SYSLOG_FACILITY", &get, &length) >= 0) {
		if (length == 17 || length == 18) {
			facility = ((char *)get)[16] - '0';
			if (length == 18) {
				facility *= 10;
				facility += ((char *)get)[17] - '0';
			}
			if (facility < 0 || 23 < facility) {
				dbgprintf("The value of the 'FACILITY' field is "
					"out of bounds: %d, resetting\n", facility);
				facility = cs.iDfltFacility;
			}
		} else {
			dbgprintf("The value of the 'FACILITY' field has an "
				"unexpected length: %d\n", length);
		}
	}

	/* Get message identifier, client pid and add ':' */
	if (sd_journal_get_data(j, "SYSLOG_IDENTIFIER", &get, &length) >= 0) {
		sys_iden = strndup(((const char*)get)+18, length-18);
	} else {
		sys_iden = strdup("journal");
	}
	if (sys_iden == NULL) {
		iRet = RS_RET_OUT_OF_MEMORY;
		goto free_message;
	}

	if (sd_journal_get_data(j, "SYSLOG_PID", &pidget, &pidlength) >= 0) {
		sys_pid = strndup(((const char*)pidget)+11, pidlength-11);
		if (sys_pid == NULL) {
			iRet = RS_RET_OUT_OF_MEMORY;
			free (sys_iden);
			goto free_message;
		}
	} else {
		sys_pid = NULL;
	}

	if (sys_pid) {
		r = asprintf(&sys_iden_help, "%s[%s]:", sys_iden, sys_pid);
	} else {
		r = asprintf(&sys_iden_help, "%s:", sys_iden);
	}

	free (sys_iden);
	free (sys_pid);

	if (-1 == r) {
		iRet = RS_RET_OUT_OF_MEMORY;
		goto finalize_it;
	}

	json = json_object_new_object();

	SD_JOURNAL_FOREACH_DATA(j, get, l) {
		/* locate equal sign, this is always present */
		equal_sign = memchr(get, '=', l);

		/* ... but we know better than to trust the specs */
		if (equal_sign == NULL) {
			errmsg.LogError(0, RS_RET_ERR, "SD_JOURNAL_FOREACH_DATA()"
				"returned a malformed field (has no '='): '%s'", (char*)get);
			continue; /* skip the entry */
		}

		/* get length of journal data prefix */
		prefixlen = ((char *)equal_sign - (char *)get);

		/* translate name fields to lumberjack names */
		parse = (char *)get;

		switch (*parse)
		{
		case '_':
			++parse;
			if (*parse == 'P') {
				if (!strncmp(parse+1, "ID=", 4)) {
					name = strdup("pid");
				} else {
					name = strndup(get, prefixlen);
				}
			} else if (*parse == 'G') {
				if (!strncmp(parse+1, "ID=", 4)) {
					name = strdup("gid");
				} else {
					name = strndup(get, prefixlen);
				}
			} else if (*parse == 'U') {
				if (!strncmp(parse+1, "ID=", 4)) {
					name = strdup("uid");
				} else {
					name = strndup(get, prefixlen);
				}
			} else if (*parse == 'E') {
				if (!strncmp(parse+1, "XE=", 4)) {
					name = strdup("exe");
				} else {
					name = strndup(get, prefixlen);
				}
			} else if (*parse == 'C') {
				parse++;
				if (*parse == 'O') {
					if (!strncmp(parse+1, "MM=", 4)) {
						name = strdup("appname");
					} else {
						name = strndup(get, prefixlen);
					}
				} else if (*parse == 'M') {
					if (!strncmp(parse+1, "DLINE=", 7)) {
						name = strdup("cmd");
					} else {
						name = strndup(get, prefixlen);
					}
				} else {
					name = strndup(get, prefixlen);
				}
			} else {
				name = strndup(get, prefixlen);
			}
			break;

		default:
			name = strndup(get, prefixlen);
			break;
		}

		if (name == NULL) {
			iRet = RS_RET_OUT_OF_MEMORY;
			goto ret;
		}

		prefixlen++; /* remove '=' */

		data = strndup(((const char*)get) + prefixlen, l - prefixlen);
		if (data == NULL) {
			iRet = RS_RET_OUT_OF_MEMORY;
			free (name);
			goto ret;
		}

		/* and save them to json object */
		jval = json_object_new_string((char *)data);
		json_object_object_add(json, name, jval);
		free (data);
		free (name);
	}
示例#10
0
tlog_grc
tlog_journal_json_reader_read(struct tlog_json_reader *reader,
                              struct json_object **pobject)
{
    struct tlog_journal_json_reader *journal_json_reader =
                                (struct tlog_journal_json_reader*)reader;
    tlog_grc grc;
    int sd_rc;
    struct json_object *object = NULL;

    /* If we ran out of time limit */
    if (journal_json_reader->last > journal_json_reader->until) {
        goto exit;
    }

    /* Advance to the next entry */
    sd_rc = sd_journal_next(journal_json_reader->journal);
    /* If failed */
    if (sd_rc < 0) {
        grc = TLOG_GRC_FROM(systemd, sd_rc);
        goto cleanup;
    /* If got an entry */
    } else if (sd_rc > 0) {
        const char *field_ptr;
        size_t field_len;
        const char *message_ptr;
        size_t message_len;

        /* Advance entry counter */
        journal_json_reader->entry++;

        /* Get the entry realtime timestamp */
        sd_rc = sd_journal_get_realtime_usec(journal_json_reader->journal,
                                             &journal_json_reader->last);
        if (sd_rc < 0) {
            grc = TLOG_GRC_FROM(systemd, sd_rc);
            goto cleanup;
        }
        if (journal_json_reader->last > journal_json_reader->until) {
            goto exit;
        }

        /* Get the entry message field data */
        sd_rc = sd_journal_get_data(journal_json_reader->journal, "MESSAGE",
                                    (const void **)&field_ptr, &field_len);
        if (sd_rc < 0) {
            grc = TLOG_GRC_FROM(systemd, sd_rc);
            goto cleanup;
        }

        /* Extract the message */
        message_ptr = (const char *)memchr(field_ptr, '=', field_len);
        if (message_ptr == NULL) {
            grc = TLOG_RC_FAILURE;
            goto cleanup;
        }
        message_ptr++;
        message_len = field_len - (message_ptr - field_ptr);

        /* Parse the message */
        object = json_tokener_parse_ex(journal_json_reader->tok,
                                       message_ptr, message_len);
        if (object == NULL) {
            grc = TLOG_GRC_FROM(
                    json, json_tokener_get_error(journal_json_reader->tok));
            goto cleanup;
        }
    }

exit:
    *pobject = object;
    object = NULL;
    grc = TLOG_RC_OK;
cleanup:
    json_object_put(object);
    return grc;
}
示例#11
0
/* Read journal log while data are available, each read() reads one
 * record of printk buffer.
 */
static rsRetVal
readjournal() {
	DEFiRet;

	struct timeval tv;
	uint64_t timestamp;

	struct json_object *json = NULL;
	int r;

	/* Information from messages */
	char *message;
	char *sys_pid;
	char *sys_iden;
	char *sys_iden_help;

	const void *get;
	const void *pidget;
	char *parse;
	char *get2;
	size_t length;
	size_t pidlength;

	const void *equal_sign;
	struct json_object *jval;
	char *data;
	char *name;
	size_t l;

	long prefixlen = 0;

	int priority = 0;
	int facility = 0;

	/* Get message text */
	if (sd_journal_get_data(j, "MESSAGE", &get, &length) < 0) {
		logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar *)"log message from journal doesn't have MESSAGE", 0);
		iRet = RS_RET_OK;
		goto ret;
	}
	message = strndup(get+8, length-8);
	if (message == NULL) {
		iRet = RS_RET_OUT_OF_MEMORY;
		goto ret;
	}

	/* Get message priority */
	if (sd_journal_get_data(j, "PRIORITY", &get, &length) >= 0) {
		get2 = strndup(get, length);
		priority = ((char *)get2)[9] - '0';
		free (get2);
	}

	/* Get syslog facility */
	if (sd_journal_get_data(j, "SYSLOG_FACILITY", &get, &length) >= 0) {
		get2 = strndup(get, length);
		char f = ((char *)get2)[16];
		if (f >= '0' && f <= '9') {
			facility += f - '0';
		}
		f = ((char *)get2)[17];
		if (f >= '0' && f <= '9') {
			facility *= 10;
			facility += (f - '0');
		}
		free (get2);
	} else {
		/* message is missing facility -> internal systemd journal msg, drop */
		iRet = RS_RET_OK;
		goto free_message;
	}

	/* Get message identifier, client pid and add ':' */
	if (sd_journal_get_data(j, "SYSLOG_IDENTIFIER", &get, &length) >= 0) {
		sys_iden = strndup(get+18, length-18);
	} else {
		sys_iden = strdup("journal");
	}
	if (sys_iden == NULL) {
		iRet = RS_RET_OUT_OF_MEMORY;
		goto free_message;
	}

	if (sd_journal_get_data(j, "SYSLOG_PID", &pidget, &pidlength) >= 0) {
		sys_pid = strndup(pidget+11, pidlength-11);
		if (sys_pid == NULL) {
			iRet = RS_RET_OUT_OF_MEMORY;
			free (sys_iden);
			goto free_message;
		}
	} else {
		sys_pid = NULL;
	}

	if (sys_pid) {
		r = asprintf(&sys_iden_help, "%s[%s]:", sys_iden, sys_pid);
	} else {
		r = asprintf(&sys_iden_help, "%s:", sys_iden);
	}

	free (sys_iden);
	free (sys_pid);

	if (-1 == r) {
		iRet = RS_RET_OUT_OF_MEMORY;
		goto finalize_it;
	}

	json = json_object_new_object();

	SD_JOURNAL_FOREACH_DATA(j, get, l) {
		/* locate equal sign, this is always present */
		equal_sign = memchr(get, '=', l);

		/* ... but we know better than to trust the specs */
		if (equal_sign == NULL) {
			errmsg.LogError(0, RS_RET_ERR, "SD_JOURNAL_FOREACH_DATA()"
				"returned a malformed field (has no '='): '%s'", get);
			continue; /* skip the entry */
		}

		/* get length of journal data prefix */
		prefixlen = ((char *)equal_sign - (char *)get);

		/* translate name fields to lumberjack names */
		parse = (char *)get;

		switch (*parse)
		{
		case '_':
			++parse;
			if (*parse == 'P') {
				if (!strncmp(parse+1, "ID=", 4)) {
					name = strdup("pid");
				} else {
					name = strndup(get, prefixlen);
				}
			} else if (*parse == 'G') {
				if (!strncmp(parse+1, "ID=", 4)) {
					name = strdup("gid");
				} else {
					name = strndup(get, prefixlen);
				}
			} else if (*parse == 'U') {
				if (!strncmp(parse+1, "ID=", 4)) {
					name = strdup("uid");
				} else {
					name = strndup(get, prefixlen);
				}
			} else if (*parse == 'E') {
				if (!strncmp(parse+1, "XE=", 4)) {
					name = strdup("exe");
				} else {
					name = strndup(get, prefixlen);
				}
			} else if (*parse == 'C') {
				parse++;
				if (*parse == 'O') {
					if (!strncmp(parse+1, "MM=", 4)) {
						name = strdup("appname");
					} else {
						name = strndup(get, prefixlen);
					}
				} else if (*parse == 'M') {
					if (!strncmp(parse+1, "DLINE=", 7)) {
						name = strdup("cmd");
					} else {
						name = strndup(get, prefixlen);
					}
				} else {
					name = strndup(get, prefixlen);
				}
			} else {
				name = strndup(get, prefixlen);
			}
			break;

		default:
			name = strndup(get, prefixlen);
			break;
		}

		if (name == NULL) {
			iRet = RS_RET_OUT_OF_MEMORY;
			goto ret;
		}

		prefixlen++; /* remove '=' */

		data = strndup(get + prefixlen, l - prefixlen);
		if (data == NULL) {
			iRet = RS_RET_OUT_OF_MEMORY;
			free (name);
			goto ret;
		}

		/* and save them to json object */
		jval = json_object_new_string((char *)data);
		json_object_object_add(json, name, jval);
		free (data);
		free (name);
	}
示例#12
0
QStringList UnitModel::getLastJrnlEntries(QString unit) const
{
  QString match1, match2;
  int r, jflags;
  QStringList reply;
  const void *data;
  size_t length;
  uint64_t time;
  sd_journal *journal;

  if (!userBus.isEmpty())
  {
    match1 = QString("USER_UNIT=" + unit);
    jflags = (SD_JOURNAL_LOCAL_ONLY | SD_JOURNAL_CURRENT_USER);
  }
  else
  {
    match1 = QString("_SYSTEMD_UNIT=" + unit);
    match2 = QString("UNIT=" + unit);
    jflags = (SD_JOURNAL_LOCAL_ONLY | SD_JOURNAL_SYSTEM);
  }

  r = sd_journal_open(&journal, jflags);
  if (r != 0)
  {
    qDebug() << "Failed to open journal";
    return reply;
  }

  sd_journal_flush_matches(journal);

  r = sd_journal_add_match(journal, match1.toUtf8(), 0);
  if (r != 0)
    return reply;

  if (!match2.isEmpty())
  {
    sd_journal_add_disjunction(journal);
    r = sd_journal_add_match(journal, match2.toUtf8(), 0);
    if (r != 0)
      return reply;
  }


  r = sd_journal_seek_tail(journal);
  if (r != 0)
    return reply;

  // Fetch the last 5 entries
  for (int i = 0; i < 5; ++i)
  {
    r = sd_journal_previous(journal);
    if (r == 1)
    {
      QString line;

      // Get the date and time
      r = sd_journal_get_realtime_usec(journal, &time);
      if (r == 0)
      {
        QDateTime date;
        date.setMSecsSinceEpoch(time/1000);
        line.append(date.toString("yyyy.MM.dd hh:mm"));
      }

      // Color messages according to priority
      r = sd_journal_get_data(journal, "PRIORITY", &data, &length);
      if (r == 0)
      {
        int prio = QString::fromUtf8((const char *)data, length).section('=',1).toInt();
        if (prio <= 3)
          line.append("<span style='color:tomato;'>");
        else if (prio == 4)
          line.append("<span style='color:khaki;'>");
        else
          line.append("<span style='color:palegreen;'>");
      }

      // Get the message itself
      r = sd_journal_get_data(journal, "MESSAGE", &data, &length);
      if (r == 0)
      {
        line.append(": " + QString::fromUtf8((const char *)data, length).section('=',1) + "</span>");
        if (line.length() > 195)
          line = QString(line.left(195) + "..." + "</span>");
        reply << line;
      }
    }
    else // previous failed, no more entries
      return reply;
  }

  sd_journal_close(journal);

  return reply;
}