Hi all,<div><br></div><div>This is more like a RFC patch, it can&#39;t even compile well... However, I&#39;d like to gather some information here on the mailing list to make sure that I&#39;m on the right track and my work would be liked by others.</div>
<div><br></div><div>This &#39;category&#39; model is mainly after the design of gstreamer. So we have a &#39;pa_log_category_t&#39; type to show what kind of category it&#39;s, and in its category, we can specify a threshold and the color to display.  (look at the changes in these two files src/pulsecore/log.h and src/pulsecore/log.c for more details.)</div>
<div><br></div><div>Now the main problem to me is that the usage is not so developer-friendly. Any place where we use pa_log related functions, I have to specify the macro PA_LOG_CATEGORY_DEFAULT. That&#39;s almost everywhere... But yes, it should only be written for only and after that other developers should be OK with that.</div>
<div><br></div><div>Any comments are welcome!</div><div><div class="gmail_quote">2012/5/24 Deng Zhengrong <span dir="ltr">&lt;<a href="mailto:dzrongg@gmail.com" target="_blank">dzrongg@gmail.com</a>&gt;</span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
---<br>
 src/modules/module-loopback.c  |    5 ++<br>
 src/pulse/channelmap.c         |    2 +<br>
 src/pulse/client-conf.c        |    2 +<br>
 src/pulse/context.c            |    2 +<br>
 src/pulse/ext-device-manager.c |    2 +<br>
 src/pulse/ext-device-restore.c |    2 +<br>
 src/pulse/ext-stream-restore.c |    2 +<br>
 src/pulse/format.c             |    2 +<br>
 src/pulse/introspect.c         |    2 +<br>
 src/pulse/mainloop-api.c       |    2 +<br>
 src/pulse/mainloop-signal.c    |    2 +<br>
 src/pulse/mainloop.c           |    2 +<br>
 src/pulse/operation.c          |    2 +<br>
 src/pulse/proplist.c           |    2 +<br>
 src/pulse/sample.c             |    2 +<br>
 src/pulse/scache.c             |    2 +<br>
 src/pulse/stream.c             |    2 +<br>
 src/pulse/subscribe.c          |    2 +<br>
 src/pulse/thread-mainloop.c    |    2 +<br>
 src/pulse/timeval.c            |    2 +<br>
 src/pulse/utf8.c               |    2 +<br>
 src/pulse/util.c               |    2 +<br>
 src/pulse/volume.c             |    2 +<br>
 src/pulse/xmalloc.c            |    2 +<br>
 src/pulsecore/authkey.c        |    2 +<br>
 src/pulsecore/conf-parser.c    |    2 +<br>
 src/pulsecore/core-error.c     |    2 +<br>
 src/pulsecore/core-rtclock.c   |    2 +<br>
 src/pulsecore/core-util.c      |    2 +<br>
 src/pulsecore/dynarray.c       |    2 +<br>
 src/pulsecore/flist.c          |    2 +<br>
 src/pulsecore/iochannel.c      |    2 +<br>
 src/pulsecore/ioline.c         |    2 +<br>
 src/pulsecore/ipacl.c          |    2 +<br>
 src/pulsecore/lock-autospawn.c |    2 +<br>
 src/pulsecore/log.c            |  104 ++++++++++++++++++++++++++++++++++++++--<br>
 src/pulsecore/log.h            |   39 +++++++++++----<br>
 src/pulsecore/macro.h          |    2 +-<br>
 src/pulsecore/ratelimit.c      |    2 +<br>
 39 files changed, 205 insertions(+), 15 deletions(-)<br>
<br>
diff --git a/src/modules/module-loopback.c b/src/modules/module-loopback.c<br>
index 1a69445..3b9bb90 100644<br>
--- a/src/modules/module-loopback.c<br>
+++ b/src/modules/module-loopback.c<br>
@@ -59,6 +59,9 @@ PA_MODULE_USAGE(<br>
         &quot;sink_dont_move=&lt;boolean&gt; &quot;<br>
         &quot;remix=&lt;remix channels?&gt; &quot;);<br>
<br>
+PA_LOG_CATEGORY_STATIC(module_loopback_category);<br>
+#define PA_LOG_CATEGORY_DEFAULT module_loopback_category<br>
+<br>
 #define DEFAULT_LATENCY_MSEC 200<br>
<br>
 #define MEMBLOCKQ_MAXLENGTH (1024*1024*16)<br>
@@ -663,6 +666,8 @@ int pa__init(pa_module *m) {<br>
<br>
     pa_assert(m);<br>
<br>
+    PA_LOG_CATEGORY_INIT(module_loopback_category, &quot;loopback&quot;, 0);<br>
+<br>
     if (!(ma = pa_modargs_new(m-&gt;argument, valid_modargs))) {<br>
         pa_log(&quot;Failed to parse module arguments&quot;);<br>
         goto fail;<br>
diff --git a/src/pulse/channelmap.c b/src/pulse/channelmap.c<br>
index 0d199f3..f375cbf 100644<br>
--- a/src/pulse/channelmap.c<br>
+++ b/src/pulse/channelmap.c<br>
@@ -38,6 +38,8 @@<br>
<br>
 #include &quot;channelmap.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CHANNELMAP<br>
+<br>
 const char *const table[PA_CHANNEL_POSITION_MAX] = {<br>
     [PA_CHANNEL_POSITION_MONO] = &quot;mono&quot;,<br>
<br>
diff --git a/src/pulse/client-conf.c b/src/pulse/client-conf.c<br>
index e2c2aae..1801062 100644<br>
--- a/src/pulse/client-conf.c<br>
+++ b/src/pulse/client-conf.c<br>
@@ -40,6 +40,8 @@<br>
<br>
 #include &quot;client-conf.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CORE<br>
+<br>
 #define DEFAULT_CLIENT_CONFIG_FILE PA_DEFAULT_CONFIG_DIR PA_PATH_SEP &quot;client.conf&quot;<br>
 #define DEFAULT_CLIENT_CONFIG_FILE_USER &quot;client.conf&quot;<br>
<br>
diff --git a/src/pulse/context.c b/src/pulse/context.c<br>
index 5bd3448..14520e5 100644<br>
--- a/src/pulse/context.c<br>
+++ b/src/pulse/context.c<br>
@@ -71,6 +71,8 @@<br>
 #include &quot;internal.h&quot;<br>
 #include &quot;context.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CONTEXT<br>
+<br>
 void pa_command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);<br>
<br>
 static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {<br>
diff --git a/src/pulse/ext-device-manager.c b/src/pulse/ext-device-manager.c<br>
index f2ea63a..2dca36c 100644<br>
--- a/src/pulse/ext-device-manager.c<br>
+++ b/src/pulse/ext-device-manager.c<br>
@@ -35,6 +35,8 @@<br>
 #include &quot;internal.h&quot;<br>
 #include &quot;ext-device-manager.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CORE<br>
+<br>
 enum {<br>
     SUBCOMMAND_TEST,<br>
     SUBCOMMAND_READ,<br>
diff --git a/src/pulse/ext-device-restore.c b/src/pulse/ext-device-restore.c<br>
index 25d33d1..2174d82 100644<br>
--- a/src/pulse/ext-device-restore.c<br>
+++ b/src/pulse/ext-device-restore.c<br>
@@ -37,6 +37,8 @@<br>
 #include &quot;internal.h&quot;<br>
 #include &quot;ext-device-restore.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CORE<br>
+<br>
 /* Protocol extension commands */<br>
 enum {<br>
     SUBCOMMAND_TEST,<br>
diff --git a/src/pulse/ext-stream-restore.c b/src/pulse/ext-stream-restore.c<br>
index 1f72c1c..569bcb0 100644<br>
--- a/src/pulse/ext-stream-restore.c<br>
+++ b/src/pulse/ext-stream-restore.c<br>
@@ -33,6 +33,8 @@<br>
 #include &quot;internal.h&quot;<br>
 #include &quot;ext-stream-restore.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CORE<br>
+<br>
 enum {<br>
     SUBCOMMAND_TEST,<br>
     SUBCOMMAND_READ,<br>
diff --git a/src/pulse/format.c b/src/pulse/format.c<br>
index 542d119..972a6d0 100644<br>
--- a/src/pulse/format.c<br>
+++ b/src/pulse/format.c<br>
@@ -36,6 +36,8 @@<br>
<br>
 #include &quot;format.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CORE<br>
+<br>
 #define PA_JSON_MIN_KEY &quot;min&quot;<br>
 #define PA_JSON_MAX_KEY &quot;max&quot;<br>
<br>
diff --git a/src/pulse/introspect.c b/src/pulse/introspect.c<br>
index 38a9d1c..1ec638f 100644<br>
--- a/src/pulse/introspect.c<br>
+++ b/src/pulse/introspect.c<br>
@@ -35,6 +35,8 @@<br>
 #include &quot;internal.h&quot;<br>
 #include &quot;introspect.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CORE<br>
+<br>
 /*** Statistics ***/<br>
<br>
 static void context_stat_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {<br>
diff --git a/src/pulse/mainloop-api.c b/src/pulse/mainloop-api.c<br>
index 45539cc..be76c27 100644<br>
--- a/src/pulse/mainloop-api.c<br>
+++ b/src/pulse/mainloop-api.c<br>
@@ -32,6 +32,8 @@<br>
<br>
 #include &quot;mainloop-api.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CORE<br>
+<br>
 struct once_info {<br>
     void (*callback)(pa_mainloop_api*m, void *userdata);<br>
     void *userdata;<br>
diff --git a/src/pulse/mainloop-signal.c b/src/pulse/mainloop-signal.c<br>
index 9482fe3..b0a9453 100644<br>
--- a/src/pulse/mainloop-signal.c<br>
+++ b/src/pulse/mainloop-signal.c<br>
@@ -45,6 +45,8 @@<br>
<br>
 #include &quot;mainloop-signal.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CORE<br>
+<br>
 struct pa_signal_event {<br>
     int sig;<br>
 #ifdef HAVE_SIGACTION<br>
diff --git a/src/pulse/mainloop.c b/src/pulse/mainloop.c<br>
index 5c0345e..7031f8f 100644<br>
--- a/src/pulse/mainloop.c<br>
+++ b/src/pulse/mainloop.c<br>
@@ -51,6 +51,8 @@<br>
 #include &quot;mainloop.h&quot;<br>
 #include &quot;internal.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CORE<br>
+<br>
 struct pa_io_event {<br>
     pa_mainloop *mainloop;<br>
     pa_bool_t dead:1;<br>
diff --git a/src/pulse/operation.c b/src/pulse/operation.c<br>
index fe160a3..f14466d 100644<br>
--- a/src/pulse/operation.c<br>
+++ b/src/pulse/operation.c<br>
@@ -30,6 +30,8 @@<br>
 #include &quot;internal.h&quot;<br>
 #include &quot;operation.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CORE<br>
+<br>
 PA_STATIC_FLIST_DECLARE(operations, 0, pa_xfree);<br>
<br>
 pa_operation *pa_operation_new(pa_context *c, pa_stream *s, pa_operation_cb_t cb, void *userdata) {<br>
diff --git a/src/pulse/proplist.c b/src/pulse/proplist.c<br>
index 649138c..1296bc8 100644<br>
--- a/src/pulse/proplist.c<br>
+++ b/src/pulse/proplist.c<br>
@@ -35,6 +35,8 @@<br>
<br>
 #include &quot;proplist.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CORE<br>
+<br>
 struct property {<br>
     char *key;<br>
     void *value;<br>
diff --git a/src/pulse/sample.c b/src/pulse/sample.c<br>
index b613612..5731736 100644<br>
--- a/src/pulse/sample.c<br>
+++ b/src/pulse/sample.c<br>
@@ -35,6 +35,8 @@<br>
<br>
 #include &quot;sample.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CORE<br>
+<br>
 static const size_t size_table[] = {<br>
     [PA_SAMPLE_U8] = 1,<br>
     [PA_SAMPLE_ULAW] = 1,<br>
diff --git a/src/pulse/scache.c b/src/pulse/scache.c<br>
index 3fad82a..60bc803 100644<br>
--- a/src/pulse/scache.c<br>
+++ b/src/pulse/scache.c<br>
@@ -36,6 +36,8 @@<br>
 #include &quot;internal.h&quot;<br>
 #include &quot;scache.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CORE<br>
+<br>
 int pa_stream_connect_upload(pa_stream *s, size_t length) {<br>
     pa_tagstruct *t;<br>
     uint32_t tag;<br>
diff --git a/src/pulse/stream.c b/src/pulse/stream.c<br>
index 39338c1..52c9ae4 100644<br>
--- a/src/pulse/stream.c<br>
+++ b/src/pulse/stream.c<br>
@@ -44,6 +44,8 @@<br>
 #include &quot;internal.h&quot;<br>
 #include &quot;stream.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CORE<br>
+<br>
 #define AUTO_TIMING_INTERVAL_START_USEC (10*PA_USEC_PER_MSEC)<br>
 #define AUTO_TIMING_INTERVAL_END_USEC (1500*PA_USEC_PER_MSEC)<br>
<br>
diff --git a/src/pulse/subscribe.c b/src/pulse/subscribe.c<br>
index a6ad238..4cf002a 100644<br>
--- a/src/pulse/subscribe.c<br>
+++ b/src/pulse/subscribe.c<br>
@@ -31,6 +31,8 @@<br>
 #include &quot;internal.h&quot;<br>
 #include &quot;subscribe.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CORE<br>
+<br>
 void pa_command_subscribe_event(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {<br>
     pa_context *c = userdata;<br>
     pa_subscription_event_type_t e;<br>
diff --git a/src/pulse/thread-mainloop.c b/src/pulse/thread-mainloop.c<br>
index aa56a92..8e822b8 100644<br>
--- a/src/pulse/thread-mainloop.c<br>
+++ b/src/pulse/thread-mainloop.c<br>
@@ -43,6 +43,8 @@<br>
<br>
 #include &quot;thread-mainloop.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CORE<br>
+<br>
 struct pa_threaded_mainloop {<br>
     pa_mainloop *real_mainloop;<br>
     volatile int n_waiting, n_waiting_for_accept;<br>
diff --git a/src/pulse/timeval.c b/src/pulse/timeval.c<br>
index a394dbe..a993b2b 100644<br>
--- a/src/pulse/timeval.c<br>
+++ b/src/pulse/timeval.c<br>
@@ -36,6 +36,8 @@<br>
<br>
 #include &quot;timeval.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CORE<br>
+<br>
 struct timeval *pa_gettimeofday(struct timeval *tv) {<br>
     pa_assert(tv);<br>
<br>
diff --git a/src/pulse/utf8.c b/src/pulse/utf8.c<br>
index 773a1f8..0962515 100644<br>
--- a/src/pulse/utf8.c<br>
+++ b/src/pulse/utf8.c<br>
@@ -62,6 +62,8 @@<br>
<br>
 #include &quot;utf8.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CORE<br>
+<br>
 #define FILTER_CHAR &#39;_&#39;<br>
<br>
 static inline pa_bool_t is_unicode_valid(uint32_t ch) {<br>
diff --git a/src/pulse/util.c b/src/pulse/util.c<br>
index 6656bc3..75bef42 100644<br>
--- a/src/pulse/util.c<br>
+++ b/src/pulse/util.c<br>
@@ -64,6 +64,8 @@<br>
<br>
 #include &quot;util.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CORE<br>
+<br>
 char *pa_get_user_name(char *s, size_t l) {<br>
     const char *p;<br>
     char *name = NULL;<br>
diff --git a/src/pulse/volume.c b/src/pulse/volume.c<br>
index cf0a226..3478893 100644<br>
--- a/src/pulse/volume.c<br>
+++ b/src/pulse/volume.c<br>
@@ -34,6 +34,8 @@<br>
<br>
 #include &quot;volume.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CORE<br>
+<br>
 int pa_cvolume_equal(const pa_cvolume *a, const pa_cvolume *b) {<br>
     int i;<br>
     pa_assert(a);<br>
diff --git a/src/pulse/xmalloc.c b/src/pulse/xmalloc.c<br>
index e17a354..840c9df 100644<br>
--- a/src/pulse/xmalloc.c<br>
+++ b/src/pulse/xmalloc.c<br>
@@ -35,6 +35,8 @@<br>
<br>
 #include &quot;xmalloc.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CORE<br>
+<br>
 /* Make sure not to allocate more than this much memory. */<br>
 #define MAX_ALLOC_SIZE (1024*1024*96) /* 96MB */<br>
<br>
diff --git a/src/pulsecore/authkey.c b/src/pulsecore/authkey.c<br>
index ac81513..6ad4574 100644<br>
--- a/src/pulsecore/authkey.c<br>
+++ b/src/pulsecore/authkey.c<br>
@@ -42,6 +42,8 @@<br>
<br>
 #include &quot;authkey.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CORE<br>
+<br>
 /* Generate a new authorization key, store it in file fd and return it in *data  */<br>
 static int generate(int fd, void *ret_data, size_t length) {<br>
     ssize_t r;<br>
diff --git a/src/pulsecore/conf-parser.c b/src/pulsecore/conf-parser.c<br>
index 7152955..8098e70 100644<br>
--- a/src/pulsecore/conf-parser.c<br>
+++ b/src/pulsecore/conf-parser.c<br>
@@ -36,6 +36,8 @@<br>
<br>
 #include &quot;conf-parser.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CORE<br>
+<br>
 #define WHITESPACE &quot; \t\n&quot;<br>
 #define COMMENTS &quot;#;\n&quot;<br>
<br>
diff --git a/src/pulsecore/core-error.c b/src/pulsecore/core-error.c<br>
index 4d930a0..f731be5 100644<br>
--- a/src/pulsecore/core-error.c<br>
+++ b/src/pulsecore/core-error.c<br>
@@ -38,6 +38,8 @@<br>
<br>
 #include &quot;core-error.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CORE<br>
+<br>
 PA_STATIC_TLS_DECLARE(cstrerror, pa_xfree);<br>
<br>
 const char* pa_cstrerror(int errnum) {<br>
diff --git a/src/pulsecore/core-rtclock.c b/src/pulsecore/core-rtclock.c<br>
index 6632cc6..537cfb1 100644<br>
--- a/src/pulsecore/core-rtclock.c<br>
+++ b/src/pulsecore/core-rtclock.c<br>
@@ -54,6 +54,8 @@<br>
<br>
 #include &quot;core-rtclock.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CORE<br>
+<br>
 #ifdef OS_IS_WIN32<br>
 static int64_t counter_freq = 0;<br>
 #endif<br>
diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c<br>
index 61f980e..1044dad 100644<br>
--- a/src/pulsecore/core-util.c<br>
+++ b/src/pulsecore/core-util.c<br>
@@ -138,6 +138,8 @@<br>
<br>
 #include &quot;core-util.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CORE<br>
+<br>
 /* Not all platforms have this */<br>
 #ifndef MSG_NOSIGNAL<br>
 #define MSG_NOSIGNAL 0<br>
diff --git a/src/pulsecore/dynarray.c b/src/pulsecore/dynarray.c<br>
index 78b2eb9..62c58c1 100644<br>
--- a/src/pulsecore/dynarray.c<br>
+++ b/src/pulsecore/dynarray.c<br>
@@ -31,6 +31,8 @@<br>
<br>
 #include &quot;dynarray.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CORE<br>
+<br>
 /* If the array becomes to small, increase its size by 25 entries */<br>
 #define INCREASE_BY 25<br>
<br>
diff --git a/src/pulsecore/flist.c b/src/pulsecore/flist.c<br>
index 0aa95c7..03475e2 100644<br>
--- a/src/pulsecore/flist.c<br>
+++ b/src/pulsecore/flist.c<br>
@@ -37,6 +37,8 @@<br>
<br>
 #include &quot;flist.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CORE<br>
+<br>
 #define FLIST_SIZE 128<br>
<br>
 /* Atomic table indices contain<br>
diff --git a/src/pulsecore/iochannel.c b/src/pulsecore/iochannel.c<br>
index fa3d767..f020535 100644<br>
--- a/src/pulsecore/iochannel.c<br>
+++ b/src/pulsecore/iochannel.c<br>
@@ -43,6 +43,8 @@<br>
<br>
 #include &quot;iochannel.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CORE<br>
+<br>
 struct pa_iochannel {<br>
     int ifd, ofd;<br>
     int ifd_type, ofd_type;<br>
diff --git a/src/pulsecore/ioline.c b/src/pulsecore/ioline.c<br>
index a18188d..5781d91 100644<br>
--- a/src/pulsecore/ioline.c<br>
+++ b/src/pulsecore/ioline.c<br>
@@ -39,6 +39,8 @@<br>
<br>
 #include &quot;ioline.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CORE<br>
+<br>
 #define BUFFER_LIMIT (64*1024)<br>
 #define READ_SIZE (1024)<br>
<br>
diff --git a/src/pulsecore/ipacl.c b/src/pulsecore/ipacl.c<br>
index 5455d0e..39beaa2 100644<br>
--- a/src/pulsecore/ipacl.c<br>
+++ b/src/pulsecore/ipacl.c<br>
@@ -49,6 +49,8 @@<br>
<br>
 #include &quot;ipacl.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CORE<br>
+<br>
 struct acl_entry {<br>
     PA_LLIST_FIELDS(struct acl_entry);<br>
     int family;<br>
diff --git a/src/pulsecore/lock-autospawn.c b/src/pulsecore/lock-autospawn.c<br>
index b1d414b..a936a86 100644<br>
--- a/src/pulsecore/lock-autospawn.c<br>
+++ b/src/pulsecore/lock-autospawn.c<br>
@@ -42,6 +42,8 @@<br>
<br>
 #include &quot;lock-autospawn.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CORE<br>
+<br>
 /* So, why do we have this complex code here with threads and pipes<br>
  * and stuff? For two reasons: POSIX file locks are per-process, not<br>
  * per-file descriptor. That means that two contexts within the same<br>
diff --git a/src/pulsecore/log.c b/src/pulsecore/log.c<br>
index 8eaef54..628aa59 100644<br>
--- a/src/pulsecore/log.c<br>
+++ b/src/pulsecore/log.c<br>
@@ -50,6 +50,8 @@<br>
 #include &lt;pulsecore/once.h&gt;<br>
 #include &lt;pulsecore/ratelimit.h&gt;<br>
 #include &lt;pulsecore/thread.h&gt;<br>
+#include &lt;pulsecore/llist.h&gt;<br>
+#include &lt;pulsecore/mutex.h&gt;<br>
<br>
 #include &quot;log.h&quot;<br>
<br>
@@ -63,6 +65,20 @@<br>
 #define ENV_LOG_BACKTRACE &quot;PULSE_LOG_BACKTRACE&quot;<br>
 #define ENV_LOG_BACKTRACE_SKIP &quot;PULSE_LOG_BACKTRACE_SKIP&quot;<br>
 #define ENV_LOG_NO_RATELIMIT &quot;PULSE_LOG_NO_RATE_LIMIT&quot;<br>
+#define ENV_LOG_DEBUG &quot;PULSE_LOG_DEBUG&quot;<br>
+<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CORE<br>
+<br>
+struct pa_log_category {<br>
+    PA_LLIST_FIELDS(pa_log_category_t);<br>
+    int threshold;<br>
+    int color;<br>
+    const char *name;<br>
+    const char *description;<br>
+};<br>
+<br>
+static pa_static_mutex categories_mutex = PA_STATIC_MUTEX_INIT;<br>
+static pa_log_category_t *categories = NULL;<br>
<br>
 static char *ident = NULL; /* in local charset format */<br>
 static pa_log_target_t target = PA_LOG_STDERR, target_override;<br>
@@ -207,11 +223,21 @@ static char* get_backtrace(unsigned show_nframes) {<br>
<br>
 #endif<br>
<br>
+pa_log_category_t *PA_LOG_CAT_CORE = NULL;<br>
+pa_log_category_t *PA_LOG_CAT_CHANNELMAP = NULL;<br>
+pa_log_category_t *PA_LOG_CAT_CONTEXT = NULL;<br>
+static void init_log_categories(void) {<br>
+    PA_LOG_CAT_CORE = pa_log_category_new(&quot;core&quot;, 0, &quot;pulsecore&quot;);<br>
+    PA_LOG_CAT_CONTEXT = pa_log_category_new(&quot;channelmap&quot;, 0, &quot;channelmap&quot;);<br>
+}<br>
+<br>
 static void init_defaults(void) {<br>
     PA_ONCE_BEGIN {<br>
<br>
         const char *e;<br>
<br>
+        init_log_categories();<br>
+<br>
         if (!ident) {<br>
             char binary[256];<br>
             if (pa_get_binary_name(binary, sizeof(binary)))<br>
@@ -262,10 +288,37 @@ static void init_defaults(void) {<br>
         if (getenv(ENV_LOG_NO_RATELIMIT))<br>
             no_rate_limit = TRUE;<br>
<br>
+        if ((e = getenv(ENV_LOG_DEBUG)))<br>
+            parse_log_debug(e);<br>
+<br>
     } PA_ONCE_END;<br>
 }<br>
<br>
+void parse_log_debug(const char *debug)<br>
+{<br>
+    const char *state = NULL;<br>
+    const char *p;<br>
+<br>
+    /*<br>
+    while ((p = pa_split(debug, &quot;,&quot;, &amp;state))) {<br>
+        if (strchr(p, &#39;:&#39;)) {<br>
+        } else {<br>
+        }<br>
+    }<br>
+    */<br>
+    pa_mutex *mutex = NULL;<br>
+    pa_log_category_t *iter;<br>
+<br>
+    mutex = pa_static_mutex_get(&amp;categories_mutex, TRUE, TRUE);<br>
+    pa_mutex_lock(mutex);<br>
+    PA_LLIST_FOREACH(iter, categories) {<br>
+        iter-&gt;threshold = 0;<br>
+    }<br>
+    pa_mutex_unlock(mutex);<br>
+}<br>
+<br>
 void pa_log_levelv_meta(<br>
+        pa_log_category_t *category,<br>
         pa_log_level_t level,<br>
         const char*file,<br>
         int line,<br>
@@ -290,6 +343,11 @@ void pa_log_levelv_meta(<br>
<br>
     init_defaults();<br>
<br>
+    if (category == NULL)<br>
+        return;<br>
+    if (level &lt; category-&gt;threshold)<br>
+        return;<br>
+<br>
     _target = target_override_set ? target_override : target;<br>
     _maximum_level = PA_MAX(maximum_level, maximum_level_override);<br>
     _show_backtrace = PA_MAX(show_backtrace, show_backtrace_override);<br>
@@ -438,6 +496,7 @@ void pa_log_levelv_meta(<br>
 }<br>
<br>
 void pa_log_level_meta(<br>
+        pa_log_category_t *category,<br>
         pa_log_level_t level,<br>
         const char*file,<br>
         int line,<br>
@@ -446,19 +505,19 @@ void pa_log_level_meta(<br>
<br>
     va_list ap;<br>
     va_start(ap, format);<br>
-    pa_log_levelv_meta(level, file, line, func, format, ap);<br>
+    pa_log_levelv_meta(category, level, file, line, func, format, ap);<br>
     va_end(ap);<br>
 }<br>
<br>
-void pa_log_levelv(pa_log_level_t level, const char *format, va_list ap) {<br>
-    pa_log_levelv_meta(level, NULL, 0, NULL, format, ap);<br>
+void pa_log_levelv(pa_log_category_t *category, pa_log_level_t level, const char *format, va_list ap) {<br>
+    pa_log_levelv_meta(category, level, NULL, 0, NULL, format, ap);<br>
 }<br>
<br>
-void pa_log_level(pa_log_level_t level, const char *format, ...) {<br>
+void pa_log_level(pa_log_category_t *category, pa_log_level_t level, const char *format, ...) {<br>
     va_list ap;<br>
<br>
     va_start(ap, format);<br>
-    pa_log_levelv_meta(level, NULL, 0, NULL, format, ap);<br>
+    pa_log_levelv_meta(category, level, NULL, 0, NULL, format, ap);<br>
     va_end(ap);<br>
 }<br>
<br>
@@ -473,3 +532,38 @@ pa_bool_t pa_log_ratelimit(pa_log_level_t level) {<br>
<br>
     return pa_ratelimit_test(&amp;ratelimit, level);<br>
 }<br>
+<br>
+pa_log_category_t *pa_log_category_new(const char *name, int color, const char *description)<br>
+{<br>
+    pa_mutex *mutex = NULL;<br>
+    pa_log_category_t *cat = pa_xnew0(pa_log_category_t, 1);<br>
+<br>
+    cat-&gt;threshold = 0;<br>
+    cat-&gt;color = color;<br>
+    cat-&gt;name = pa_xstrdup(name);<br>
+    cat-&gt;description = pa_xstrdup(description);<br>
+<br>
+    mutex = pa_static_mutex_get(&amp;categories_mutex, TRUE, TRUE);<br>
+    pa_mutex_lock(mutex);<br>
+    PA_LLIST_PREPEND(pa_log_category_t, categories, cat);<br>
+    pa_mutex_unlock(mutex);<br>
+<br>
+    return cat;<br>
+}<br>
+<br>
+static pa_log_category_t *pa_log_category_get(const char *name)<br>
+{<br>
+    pa_mutex *mutex = NULL;<br>
+    pa_log_category_t *iter;<br>
+<br>
+    mutex = pa_static_mutex_get(&amp;categories_mutex, TRUE, TRUE);<br>
+    pa_mutex_lock(mutex);<br>
+    PA_LLIST_FOREACH(iter, categories) {<br>
+        if (pa_streq(iter-&gt;name, name)) {<br>
+                pa_mutex_unlock(mutex);<br>
+                return iter;<br>
+        }<br>
+    }<br>
+    pa_mutex_unlock(mutex);<br>
+    return NULL;<br>
+}<br>
diff --git a/src/pulsecore/log.h b/src/pulsecore/log.h<br>
index 8dd056b..c10d0cc 100644<br>
--- a/src/pulsecore/log.h<br>
+++ b/src/pulsecore/log.h<br>
@@ -31,6 +31,23 @@<br>
<br>
 /* A simple logging subsystem */<br>
<br>
+typedef struct pa_log_category pa_log_category_t;<br>
+<br>
+pa_log_category_t *pa_log_category_new(const char *name,<br>
+                                       int color,<br>
+                                       const char *description);<br>
+<br>
+extern pa_log_category_t *PA_LOG_CAT_CORE;<br>
+extern pa_log_category_t *PA_LOG_CAT_CHANNELMAP;<br>
+extern pa_log_category_t *PA_LOG_CAT_CONTEXT;<br>
+<br>
+#define PA_LOG_CATEGORY_STATIC(category) \<br>
+    static pa_log_category_t *category = NULL;<br>
+#define PA_LOG_CATEGORY_INIT(category,name,color) do {                      \<br>
+    if (category == NULL)                                                   \<br>
+        category = pa_log_category_new(name, color, pa__get_description()); \<br>
+} while (0)<br>
+<br>
 /* Where to log to */<br>
 typedef enum pa_log_target {<br>
     PA_LOG_STDERR,  /* default */<br>
@@ -86,13 +103,15 @@ void pa_log_set_show_backtrace(unsigned nlevels);<br>
 void pa_log_set_skip_backtrace(unsigned nlevels);<br>
<br>
 void pa_log_level_meta(<br>
+        pa_log_category_t *category,<br>
         pa_log_level_t level,<br>
         const char*file,<br>
         int line,<br>
         const char *func,<br>
-        const char *format, ...) PA_GCC_PRINTF_ATTR(5,6);<br>
+        const char *format, ...) PA_GCC_PRINTF_ATTR(6,7);<br>
<br>
 void pa_log_levelv_meta(<br>
+        pa_log_category_t *category,<br>
         pa_log_level_t level,<br>
         const char*file,<br>
         int line,<br>
@@ -101,10 +120,12 @@ void pa_log_levelv_meta(<br>
         va_list ap);<br>
<br>
 void pa_log_level(<br>
+        pa_log_category_t *category,<br>
         pa_log_level_t level,<br>
-        const char *format, ...) PA_GCC_PRINTF_ATTR(2,3);<br>
+        const char *format, ...) PA_GCC_PRINTF_ATTR(3,4);<br>
<br>
 void pa_log_levelv(<br>
+        pa_log_category_t *category,<br>
         pa_log_level_t level,<br>
         const char *format,<br>
         va_list ap);<br>
@@ -113,12 +134,12 @@ void pa_log_levelv(<br>
<br>
 /* ISO varargs available */<br>
<br>
-#define pa_log_debug(...)  pa_log_level_meta(PA_LOG_DEBUG,  __FILE__, __LINE__, __func__, __VA_ARGS__)<br>
-#define pa_log_info(...)   pa_log_level_meta(PA_LOG_INFO,   __FILE__, __LINE__, __func__, __VA_ARGS__)<br>
-#define pa_log_notice(...) pa_log_level_meta(PA_LOG_NOTICE, __FILE__, __LINE__, __func__, __VA_ARGS__)<br>
-#define pa_log_warn(...)   pa_log_level_meta(PA_LOG_WARN,   __FILE__, __LINE__, __func__, __VA_ARGS__)<br>
-#define pa_log_error(...)  pa_log_level_meta(PA_LOG_ERROR,  __FILE__, __LINE__, __func__, __VA_ARGS__)<br>
-#define pa_logl(level, ...)  pa_log_level_meta(level,  __FILE__, __LINE__, __func__, __VA_ARGS__)<br>
+#define pa_log_debug(...)  pa_log_level_meta(PA_LOG_CATEGORY_DEFAULT, PA_LOG_DEBUG,  __FILE__, __LINE__, __func__, __VA_ARGS__)<br>
+#define pa_log_info(...)   pa_log_level_meta(PA_LOG_CATEGORY_DEFAULT, PA_LOG_INFO,   __FILE__, __LINE__, __func__, __VA_ARGS__)<br>
+#define pa_log_notice(...) pa_log_level_meta(PA_LOG_CATEGORY_DEFAULT, PA_LOG_NOTICE, __FILE__, __LINE__, __func__, __VA_ARGS__)<br>
+#define pa_log_warn(...)   pa_log_level_meta(PA_LOG_CATEGORY_DEFAULT, PA_LOG_WARN,   __FILE__, __LINE__, __func__, __VA_ARGS__)<br>
+#define pa_log_error(...)  pa_log_level_meta(PA_LOG_CATEGORY_DEFAULT, PA_LOG_ERROR,  __FILE__, __LINE__, __func__, __VA_ARGS__)<br>
+#define pa_logl(level, ...)  pa_log_level_meta(PA_LOG_CATEGORY_DEFAULT, level,  __FILE__, __LINE__, __func__, __VA_ARGS__)<br>
<br>
 #else<br>
<br>
@@ -126,7 +147,7 @@ void pa_log_levelv(<br>
 PA_GCC_UNUSED static void pa_log_##suffix(const char *format, ...) { \<br>
     va_list ap; \<br>
     va_start(ap, format); \<br>
-    pa_log_levelv_meta(level, NULL, 0, NULL, format, ap); \<br>
+    pa_log_levelv_meta(PA_LOG_CATEGORY_DEFAULT, level, NULL, 0, NULL, format, ap); \<br>
     va_end(ap); \<br>
 }<br>
<br>
diff --git a/src/pulsecore/macro.h b/src/pulsecore/macro.h<br>
index c6d7d56..3cfa0ce 100644<br>
--- a/src/pulsecore/macro.h<br>
+++ b/src/pulsecore/macro.h<br>
@@ -221,11 +221,11 @@ typedef int pa_bool_t;<br>
 #define pa_assert_se(expr)                                              \<br>
     do {                                                                \<br>
         if (PA_UNLIKELY(!(expr))) {                                     \<br>
-            pa_log_error(&quot;Assertion &#39;%s&#39; failed at %s:%u, function %s(). Aborting.&quot;, #expr , __FILE__, __LINE__, PA_PRETTY_FUNCTION); \<br>
             abort();                                                    \<br>
         }                                                               \<br>
     } while (FALSE)<br>
<br>
+//pa_log_error(&quot;Assertion &#39;%s&#39; failed at %s:%u, function %s(). Aborting.&quot;, #expr , __FILE__, __LINE__, PA_PRETTY_FUNCTION);<br>
 /* Does exactly nothing */<br>
 #define pa_nop() do {} while (FALSE)<br>
<br>
diff --git a/src/pulsecore/ratelimit.c b/src/pulsecore/ratelimit.c<br>
index a274d2c..c5c03ee 100644<br>
--- a/src/pulsecore/ratelimit.c<br>
+++ b/src/pulsecore/ratelimit.c<br>
@@ -30,6 +30,8 @@<br>
<br>
 #include &quot;ratelimit.h&quot;<br>
<br>
+#define PA_LOG_CATEGORY_DEFAULT PA_LOG_CAT_CORE<br>
+<br>
 static pa_static_mutex mutex = PA_STATIC_MUTEX_INIT;<br>
<br>
 /* Modelled after Linux&#39; lib/ratelimit.c by Dave Young<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.7.6.5<br>
<br>
</font></span></blockquote></div><br></div>