diff options
author | Florian Dold <florian.dold@gmail.com> | 2019-05-10 20:08:01 +0200 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2019-05-10 20:10:02 +0200 |
commit | c1f06ac28fef5498952994e0399312b1fc567f22 (patch) | |
tree | ad71f80bb08bfe20ff33880509263d78f334409b /src/util/common_logging.c | |
parent | d1d18e6492708a0ce758ddd8c509f21b0ecbf6a0 (diff) | |
download | gnunet-c1f06ac28fef5498952994e0399312b1fc567f22.tar.gz gnunet-c1f06ac28fef5498952994e0399312b1fc567f22.zip |
Implement asynchronous scope identifiers.
Without entering an asynchronous scope, logs are the same before. When
entering an asynchronous scope (either thread-based of
scheduler/task-based), all log lines within an asynchronous scope
contain its ID.
Currently this is only used in GNU Taler, for debugging requests across
multiple services. This allows us to get all log lines pertaining to a
particular request for a user or another service.
Diffstat (limited to 'src/util/common_logging.c')
-rw-r--r-- | src/util/common_logging.c | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/src/util/common_logging.c b/src/util/common_logging.c index 77a595878..5052134f8 100644 --- a/src/util/common_logging.c +++ b/src/util/common_logging.c | |||
@@ -95,6 +95,13 @@ struct CustomLogger | |||
95 | void *logger_cls; | 95 | void *logger_cls; |
96 | }; | 96 | }; |
97 | 97 | ||
98 | |||
99 | /** | ||
100 | * Asynchronous scope of the current thread, or NULL if we have not | ||
101 | * entered an async scope yet. | ||
102 | */ | ||
103 | static __thread struct GNUNET_AsyncScopeSave current_async_scope; | ||
104 | |||
98 | /** | 105 | /** |
99 | * The last "bulk" error message that we have been logging. | 106 | * The last "bulk" error message that we have been logging. |
100 | * Note that this message maybe truncated to the first BULK_TRACK_SIZE | 107 | * Note that this message maybe truncated to the first BULK_TRACK_SIZE |
@@ -838,6 +845,28 @@ output_message (enum GNUNET_ErrorType kind, | |||
838 | "* %s", | 845 | "* %s", |
839 | msg); | 846 | msg); |
840 | } | 847 | } |
848 | else if (GNUNET_YES == current_async_scope.have_scope) | ||
849 | { | ||
850 | static GNUNET_THREAD_LOCAL char id_buf[27]; | ||
851 | char *end; | ||
852 | |||
853 | /* We're logging, so skip_log must be currently 0. */ | ||
854 | skip_log = 100; | ||
855 | end = GNUNET_STRINGS_data_to_string (¤t_async_scope.scope_id, | ||
856 | sizeof (struct GNUNET_AsyncScopeId), | ||
857 | id_buf, | ||
858 | sizeof (id_buf) - 1); | ||
859 | GNUNET_assert (NULL != end); | ||
860 | *end = '\0'; | ||
861 | skip_log = 0; | ||
862 | FPRINTF (GNUNET_stderr, | ||
863 | "%s %s(%s) %s %s", | ||
864 | datestr, | ||
865 | comp, | ||
866 | id_buf, | ||
867 | GNUNET_error_type_to_string (kind), | ||
868 | msg); | ||
869 | } | ||
841 | else | 870 | else |
842 | { | 871 | { |
843 | FPRINTF (GNUNET_stderr, | 872 | FPRINTF (GNUNET_stderr, |
@@ -1548,6 +1577,60 @@ GNUNET_log_config_invalid (enum GNUNET_ErrorType kind, | |||
1548 | 1577 | ||
1549 | 1578 | ||
1550 | /** | 1579 | /** |
1580 | * Set the async scope for the current thread. | ||
1581 | * | ||
1582 | * @param aid the async scope identifier | ||
1583 | * @param old_scope[out] location to save the old scope | ||
1584 | */ | ||
1585 | void | ||
1586 | GNUNET_async_scope_enter (const struct GNUNET_AsyncScopeId *aid, | ||
1587 | struct GNUNET_AsyncScopeSave *old_scope) | ||
1588 | { | ||
1589 | *old_scope = current_async_scope; | ||
1590 | current_async_scope.have_scope = GNUNET_YES; | ||
1591 | current_async_scope.scope_id = *aid; | ||
1592 | } | ||
1593 | |||
1594 | |||
1595 | /** | ||
1596 | * Clear the current thread's async scope. | ||
1597 | * | ||
1598 | * @param old_scope scope to restore | ||
1599 | */ | ||
1600 | void | ||
1601 | GNUNET_async_scope_restore (struct GNUNET_AsyncScopeSave *old_scope) | ||
1602 | { | ||
1603 | current_async_scope = *old_scope; | ||
1604 | } | ||
1605 | |||
1606 | |||
1607 | /** | ||
1608 | * Generate a fresh async scope identifier. | ||
1609 | * | ||
1610 | * @param[out] aid_ret pointer to where the result is stored | ||
1611 | */ | ||
1612 | void | ||
1613 | GNUNET_async_scope_fresh (struct GNUNET_AsyncScopeId *aid_ret) | ||
1614 | { | ||
1615 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, | ||
1616 | aid_ret, | ||
1617 | sizeof (struct GNUNET_AsyncScopeId)); | ||
1618 | } | ||
1619 | |||
1620 | |||
1621 | /** | ||
1622 | * Get the current async scope. | ||
1623 | * | ||
1624 | * @param[out] scope_ret pointer to where the result is stored | ||
1625 | */ | ||
1626 | void | ||
1627 | GNUNET_async_scope_get (struct GNUNET_AsyncScopeSave *scope_ret) | ||
1628 | { | ||
1629 | *scope_ret = current_async_scope; | ||
1630 | } | ||
1631 | |||
1632 | |||
1633 | /** | ||
1551 | * Initializer | 1634 | * Initializer |
1552 | */ | 1635 | */ |
1553 | void __attribute__ ((constructor)) | 1636 | void __attribute__ ((constructor)) |