You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by ab...@apache.org on 2013/11/19 08:38:31 UTC

svn commit: r1543331 - in /incubator/celix/trunk: deployment_admin/private/include/ deployment_admin/private/src/ framework/ framework/private/include/ framework/private/src/ framework/public/include/ launcher/private/src/ log_service/private/include/ ...

Author: abroekhuis
Date: Tue Nov 19 07:38:30 2013
New Revision: 1543331

URL: http://svn.apache.org/r1543331
Log:
CELIX-87: Added framework events and improved logging, Update LogService to handle framework and bundle events.

Added:
    incubator/celix/trunk/framework/private/src/celix_log.c
      - copied, changed from r1543326, incubator/celix/trunk/deployment_admin/private/include/log.h
    incubator/celix/trunk/framework/public/include/framework_event.h
      - copied, changed from r1543326, incubator/celix/trunk/deployment_admin/private/src/log.c
    incubator/celix/trunk/framework/public/include/framework_listener.h
      - copied, changed from r1543326, incubator/celix/trunk/deployment_admin/private/include/log.h
Modified:
    incubator/celix/trunk/deployment_admin/private/include/log.h
    incubator/celix/trunk/deployment_admin/private/src/log.c
    incubator/celix/trunk/framework/CMakeLists.txt
    incubator/celix/trunk/framework/private/include/framework_private.h
    incubator/celix/trunk/framework/private/src/bundle_context.c
    incubator/celix/trunk/framework/private/src/framework.c
    incubator/celix/trunk/framework/public/include/bundle_context.h
    incubator/celix/trunk/framework/public/include/celix_log.h
    incubator/celix/trunk/launcher/private/src/launcher.c
    incubator/celix/trunk/log_service/private/include/log.h
    incubator/celix/trunk/log_service/private/src/log.c
    incubator/celix/trunk/log_service/private/src/log_service_activator.c
    incubator/celix/trunk/shell/private/src/log_command.c

Modified: incubator/celix/trunk/deployment_admin/private/include/log.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/deployment_admin/private/include/log.h?rev=1543331&r1=1543330&r2=1543331&view=diff
==============================================================================
--- incubator/celix/trunk/deployment_admin/private/include/log.h (original)
+++ incubator/celix/trunk/deployment_admin/private/include/log.h Tue Nov 19 07:38:30 2013
@@ -32,9 +32,15 @@
 #include "log_event.h"
 #include "log_store.h"
 
+#include "bundle_event.h"
+#include "framework_event.h"
+
 typedef struct log *log_pt;
 
 celix_status_t log_create(apr_pool_t *pool, log_store_pt store, log_pt *log);
 celix_status_t log_log(log_pt log, unsigned int type, properties_pt properties);
 
+celix_status_t log_bundleChanged(void * listener, bundle_event_pt event);
+celix_status_t log_frameworkEvent(void * listener, framework_event_pt event);
+
 #endif /* LOG_H_ */

Modified: incubator/celix/trunk/deployment_admin/private/src/log.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/deployment_admin/private/src/log.c?rev=1543331&r1=1543330&r2=1543331&view=diff
==============================================================================
--- incubator/celix/trunk/deployment_admin/private/src/log.c (original)
+++ incubator/celix/trunk/deployment_admin/private/src/log.c Tue Nov 19 07:38:30 2013
@@ -58,3 +58,11 @@ celix_status_t log_log(log_pt log, unsig
 
 	return status;
 }
+
+celix_status_t log_bundleChanged(void * listener, bundle_event_pt event) {
+	return CELIX_SUCCESS;
+}
+
+celix_status_t log_frameworkEvent(void * listener, framework_event_pt event) {
+	return CELIX_SUCCESS;
+}

Modified: incubator/celix/trunk/framework/CMakeLists.txt
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/framework/CMakeLists.txt?rev=1543331&r1=1543330&r2=1543331&view=diff
==============================================================================
--- incubator/celix/trunk/framework/CMakeLists.txt (original)
+++ incubator/celix/trunk/framework/CMakeLists.txt Tue Nov 19 07:38:30 2013
@@ -53,6 +53,7 @@ if (FRAMEWORK) 
 	 private/src/requirement.c private/src/resolver.c private/src/service_reference.c private/src/service_registration.c 
 	 private/src/service_registry.c private/src/service_tracker.c private/src/service_tracker_customizer.c
 	 private/src/unzip.c private/src/utils.c private/src/version.c private/src/version_range.c private/src/wire.c
+	 private/src/celix_log.c
 
 	 private/include/attribute.h public/include/framework_exports.h
 

Modified: incubator/celix/trunk/framework/private/include/framework_private.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/framework/private/include/framework_private.h?rev=1543331&r1=1543330&r2=1543331&view=diff
==============================================================================
--- incubator/celix/trunk/framework/private/include/framework_private.h (original)
+++ incubator/celix/trunk/framework/private/include/framework_private.h Tue Nov 19 07:38:30 2013
@@ -39,6 +39,7 @@
 #include "bundle_archive.h"
 #include "service_listener.h"
 #include "bundle_listener.h"
+#include "framework_listener.h"
 #include "service_registration.h"
 #include "bundle_context.h"
 
@@ -72,6 +73,9 @@ FRAMEWORK_EXPORT void fw_removeServiceLi
 FRAMEWORK_EXPORT celix_status_t fw_addBundleListener(framework_pt framework, bundle_pt bundle, bundle_listener_pt listener);
 FRAMEWORK_EXPORT celix_status_t fw_removeBundleListener(framework_pt framework, bundle_pt bundle, bundle_listener_pt listener);
 
+FRAMEWORK_EXPORT celix_status_t fw_addFrameworkListener(framework_pt framework, bundle_pt bundle, framework_listener_pt listener);
+FRAMEWORK_EXPORT celix_status_t fw_removeFrameworkListener(framework_pt framework, bundle_pt bundle, framework_listener_pt listener);
+
 FRAMEWORK_EXPORT void fw_serviceChanged(framework_pt framework, service_event_type_e eventType, service_registration_pt registration, properties_pt oldprops);
 
 FRAMEWORK_EXPORT celix_status_t fw_isServiceAssignable(framework_pt fw, bundle_pt requester, service_reference_pt reference, bool *assignable);

Modified: incubator/celix/trunk/framework/private/src/bundle_context.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/framework/private/src/bundle_context.c?rev=1543331&r1=1543330&r2=1543331&view=diff
==============================================================================
--- incubator/celix/trunk/framework/private/src/bundle_context.c (original)
+++ incubator/celix/trunk/framework/private/src/bundle_context.c Tue Nov 19 07:38:30 2013
@@ -293,6 +293,30 @@ celix_status_t bundleContext_removeBundl
     return status;
 }
 
+celix_status_t bundleContext_addFrameworkListener(bundle_context_pt context, framework_listener_pt listener) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    if (context != NULL && listener != NULL) {
+        fw_addFrameworkListener(context->framework, context->bundle, listener);
+    } else {
+        status = CELIX_ILLEGAL_ARGUMENT;
+    }
+
+    return status;
+}
+
+celix_status_t bundleContext_removeFrameworkListener(bundle_context_pt context, framework_listener_pt listener) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    if (context != NULL && listener != NULL) {
+        fw_removeFrameworkListener(context->framework, context->bundle, listener);
+    } else {
+        status = CELIX_ILLEGAL_ARGUMENT;
+    }
+
+    return status;
+}
+
 celix_status_t bundleContext_getProperty(bundle_context_pt context, const char *name, char **value) {
 	celix_status_t status = CELIX_SUCCESS;
 

Copied: incubator/celix/trunk/framework/private/src/celix_log.c (from r1543326, incubator/celix/trunk/deployment_admin/private/include/log.h)
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/framework/private/src/celix_log.c?p2=incubator/celix/trunk/framework/private/src/celix_log.c&p1=incubator/celix/trunk/deployment_admin/private/include/log.h&r1=1543326&r2=1543331&rev=1543331&view=diff
==============================================================================
--- incubator/celix/trunk/deployment_admin/private/include/log.h (original)
+++ incubator/celix/trunk/framework/private/src/celix_log.c Tue Nov 19 07:38:30 2013
@@ -17,24 +17,19 @@
  *under the License.
  */
 /*
- * log.h
+ * celix_log.c
  *
- *  \date       Apr 18, 2012
- *  \author    	<a href="mailto:celix-dev@incubator.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
+ *  \date       6 Oct 2013
+ *  \author     <a href="mailto:celix-dev@incubator.apache.org">Apache Celix Project Team</a>
+ *  \copyright  Apache License, Version 2.0
  */
 
-#ifndef LOG_H_
-#define LOG_H_
+#include "celix_log.h"
 
-#include <apr_general.h>
-
-#include "log_event.h"
-#include "log_store.h"
-
-typedef struct log *log_pt;
-
-celix_status_t log_create(apr_pool_t *pool, log_store_pt store, log_pt *log);
-celix_status_t log_log(log_pt log, unsigned int type, properties_pt properties);
-
-#endif /* LOG_H_ */
+void framework_log(framework_pt framework, framework_log_level_t level, const char *func, const char *file, int line, char *fmsg, ...) {
+	char msg[512];
+	va_list listPointer;
+	va_start(listPointer, fmsg);
+	vsprintf(msg, fmsg, listPointer);
+	printf("Log write: %s at %s, %s, %d\n", msg, func, file, line);
+}

Modified: incubator/celix/trunk/framework/private/src/framework.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/framework/private/src/framework.c?rev=1543331&r1=1543330&r2=1543331&view=diff
==============================================================================
--- incubator/celix/trunk/framework/private/src/framework.c (original)
+++ incubator/celix/trunk/framework/private/src/framework.c Tue Nov 19 07:38:30 2013
@@ -70,10 +70,11 @@ struct framework {
 	hash_map_pt installRequestMap;
 	array_list_pt serviceListeners;
 	array_list_pt bundleListeners;
+	array_list_pt frameworkListeners;
 
 	long nextBundleId;
 	struct serviceRegistry * registry;
-bundle_cache_pt cache;
+	bundle_cache_pt cache;
 
 	apr_thread_cond_t *shutdownGate;
 	apr_thread_cond_t *condition;
@@ -128,8 +129,11 @@ celix_status_t fw_refreshBundle(framewor
 celix_status_t fw_populateDependentGraph(framework_pt framework, bundle_pt exporter, hash_map_pt *map);
 
 celix_status_t fw_fireBundleEvent(framework_pt framework, bundle_event_type_e, bundle_pt bundle);
+celix_status_t fw_fireFrameworkEvent(framework_pt framework, framework_event_type_e eventType, bundle_pt bundle, celix_status_t errorCode, char *error);
 static void *APR_THREAD_FUNC fw_eventDispatcher(apr_thread_t *thd, void *fw);
+
 celix_status_t fw_invokeBundleListener(framework_pt framework, bundle_listener_pt listener, bundle_event_pt event, bundle_pt bundle);
+celix_status_t fw_invokeFrameworkListener(framework_pt framework, framework_listener_pt listener, framework_event_pt event, bundle_pt bundle);
 
 struct fw_refreshHelper {
     framework_pt framework;
@@ -150,13 +154,19 @@ struct fw_serviceListener {
 typedef struct fw_serviceListener * fw_service_listener_pt;
 
 struct fw_bundleListener {
-	apr_pool_t *pool;
 	bundle_pt bundle;
 	bundle_listener_pt listener;
 };
 
 typedef struct fw_bundleListener * fw_bundle_listener_pt;
 
+struct fw_frameworkListener {
+	bundle_pt bundle;
+	framework_listener_pt listener;
+};
+
+typedef struct fw_frameworkListener * fw_framework_listener_pt;
+
 enum event_type {
 	FRAMEWORK_EVENT_TYPE,
 	BUNDLE_EVENT_TYPE,
@@ -169,8 +179,10 @@ struct request {
 	event_type_e type;
 	array_list_pt listeners;
 
-	bundle_event_type_e eventType;
+	int eventType;
 	bundle_pt bundle;
+	celix_status_t errorCode;
+	char *error;
 
 	char *filter;
 };
@@ -180,6 +192,9 @@ typedef struct request *request_pt;
 celix_status_t framework_create(framework_pt *framework, apr_pool_t *memoryPool, properties_pt config) {
     celix_status_t status = CELIX_SUCCESS;
 
+    // framework_log(NULL, FW_LOG_INFO, __func__, __FILE__, __LINE__, "Log this message %s\n", "now!");
+    // fw_log(NULL, FW_LOG_INFO, "Log this message %s\n", "now!");
+
 	*framework = (framework_pt) apr_palloc(memoryPool, sizeof(**framework));
 	if (*framework == NULL) {
 		status = CELIX_ENOMEM;
@@ -187,6 +202,7 @@ celix_status_t framework_create(framewor
 	    apr_status_t apr_status = apr_pool_create(&(*framework)->mp, memoryPool);
         if (apr_status != APR_SUCCESS) {
             status = CELIX_FRAMEWORK_EXCEPTION;
+            fw_log(NULL, FW_LOG_ERROR,  "Could not create framework memory pool");
         } else {
             bundle_pt bundle = NULL;
             apr_pool_t *bundlePool;
@@ -197,30 +213,37 @@ celix_status_t framework_create(framewor
                 apr_status_t apr_status = bundle_create(&bundle, (*framework)->mp);
                 if (apr_status != CELIX_SUCCESS) {
                     status = CELIX_FRAMEWORK_EXCEPTION;
+                    fw_log(NULL, FW_LOG_ERROR,  "Could not create framework bundle");
                 } else {
                     apr_status_t apr_status = apr_thread_cond_create(&(*framework)->condition, (*framework)->mp);
                     if (apr_status != APR_SUCCESS) {
                         status = CELIX_FRAMEWORK_EXCEPTION;
+                        fw_log(NULL, FW_LOG_ERROR,  "Could not create framework condition");
                     } else {
                         apr_status_t apr_status = apr_thread_mutex_create(&(*framework)->mutex, APR_THREAD_MUTEX_UNNESTED, (*framework)->mp);
                         if (apr_status != APR_SUCCESS) {
                             status = CELIX_FRAMEWORK_EXCEPTION;
+                            fw_log(NULL, FW_LOG_ERROR,  "Could not create framework mutex");
                         } else {
                             apr_status_t apr_status = apr_thread_mutex_create(&(*framework)->bundleLock, APR_THREAD_MUTEX_UNNESTED, (*framework)->mp);
                             if (apr_status != APR_SUCCESS) {
                                 status = CELIX_FRAMEWORK_EXCEPTION;
+                                fw_log(NULL, FW_LOG_ERROR,  "Could not create framework bundle lock mutex");
                             } else {
                                 apr_status_t apr_status = apr_thread_mutex_create(&(*framework)->installRequestLock, APR_THREAD_MUTEX_UNNESTED, (*framework)->mp);
                                 if (apr_status != APR_SUCCESS) {
                                     status = CELIX_FRAMEWORK_EXCEPTION;
+                                    fw_log(NULL, FW_LOG_ERROR,  "Could not create framework install request lock mutex");
                                 } else {
                                 	apr_status_t apr_status = apr_thread_mutex_create(&(*framework)->dispatcherLock, APR_THREAD_MUTEX_UNNESTED, (*framework)->mp);
                                 	if (apr_status != CELIX_SUCCESS) {
 										status = CELIX_FRAMEWORK_EXCEPTION;
+										fw_log(NULL, FW_LOG_ERROR,  "Could not create framework dispatcher lock mutex");
 									} else {
 										apr_status_t apr_status = apr_thread_cond_create(&(*framework)->dispatcher, (*framework)->mp);
 										if (apr_status != APR_SUCCESS) {
 											status = CELIX_FRAMEWORK_EXCEPTION;
+											fw_log(NULL, FW_LOG_ERROR,  "Could not create framework dispatcher condition");
 										} else {
 											(*framework)->bundle = bundle;
 
@@ -240,6 +263,7 @@ celix_status_t framework_create(framewor
 											(*framework)->installRequestMap = hashMap_create(utils_stringHash, utils_stringHash, utils_stringEquals, utils_stringEquals);
 											(*framework)->serviceListeners = NULL;
 											(*framework)->bundleListeners = NULL;
+											(*framework)->frameworkListeners = NULL;
 											(*framework)->requests = NULL;
 											(*framework)->shutdownGate = NULL;
 											(*framework)->configurationMap = config;
@@ -298,6 +322,7 @@ celix_status_t framework_destroy(framewo
 	arrayList_destroy(framework->globalLockWaitersList);
 	arrayList_destroy(framework->serviceListeners);
 	arrayList_destroy(framework->bundleListeners);
+	arrayList_destroy(framework->frameworkListeners);
 	arrayList_destroy(framework->requests);
 
 	hashMap_destroy(framework->installedBundleMap, false, false);
@@ -338,13 +363,18 @@ celix_status_t fw_init(framework_pt fram
 
 
 	if (status != CELIX_SUCCESS) {
+		fw_log(NULL, FW_LOG_ERROR,  "Could not lock framework bundle");
 		framework_releaseBundleLock(framework, framework->bundle);
 		return status;
 	}
 
-	framework->requests = NULL;
+	arrayList_create(framework->mp, &framework->serviceListeners);
+	arrayList_create(framework->mp, &framework->bundleListeners);
+	arrayList_create(framework->mp, &framework->frameworkListeners);
 	arrayList_create(framework->mp, &framework->requests);
+
 	if (apr_thread_create(&framework->dispatcherThread, NULL, fw_eventDispatcher, framework, framework->mp) != APR_SUCCESS) {
+		fw_log(NULL, FW_LOG_ERROR,  "Could not create framework dispatcher thread");
 		return CELIX_FRAMEWORK_EXCEPTION;
 	}
 
@@ -361,6 +391,7 @@ celix_status_t fw_init(framework_pt fram
                 // bundleCache_delete(framework->cache);
             }
 		} else {
+			fw_log(NULL, FW_LOG_ERROR,  "Could not create bundle cache");
 		    return status;
 		}
 	}
@@ -373,11 +404,12 @@ celix_status_t fw_init(framework_pt fram
 
 	status = bundle_getCurrentModule(framework->bundle, &module);
 	if (status != CELIX_SUCCESS) {
+		fw_log(NULL, FW_LOG_ERROR,  "Could not get framework module");
 		return status;
 	}
 	wires = resolver_resolve(module);
 	if (wires == NULL) {
-		printf("Unresolved constraints in System Bundle\n");
+		fw_log(NULL, FW_LOG_ERROR,  "Unresolved constraints in System Bundle");
 		framework_releaseBundleLock(framework, framework->bundle);
 		return CELIX_BUNDLE_EXCEPTION;
 	} else {
@@ -388,6 +420,7 @@ celix_status_t fw_init(framework_pt fram
 	// reload archives from cache
 	status = bundleCache_getArchives(framework->cache, framework->mp, &archives);
 	if (status != CELIX_SUCCESS) {
+		fw_log(NULL, FW_LOG_ERROR,  "Could not get framework archive");
 	    return status;
 	} else {
 #ifdef _WIN32
@@ -435,11 +468,13 @@ celix_status_t fw_init(framework_pt fram
 #else
             printf ("%s\n", dlerror());
 #endif
+            fw_log(NULL, FW_LOG_ERROR,  "Could not get handle to framework library");
             framework_releaseBundleLock(framework, framework->bundle);
             return CELIX_START_ERROR;
         }
         
         if (bundleContext_create(framework, framework->bundle, &context) != CELIX_SUCCESS) {
+        	fw_log(NULL, FW_LOG_ERROR,  "Could not create framework bundle context");
             return CELIX_START_ERROR;
         }
         bundle_setContext(framework->bundle, context);
@@ -449,6 +484,7 @@ celix_status_t fw_init(framework_pt fram
         activator = (activator_pt) apr_palloc(framework->mp, (sizeof(*activator)));
         if (activator == NULL) {
             status = CELIX_ENOMEM;
+        	fw_log(NULL, FW_LOG_ERROR,  "Could not allocate memory");
         }  else {
 			bundle_context_pt context = NULL;
 			void * userData = NULL;
@@ -479,13 +515,6 @@ celix_status_t fw_init(framework_pt fram
                 start(userData, context);
             }
 
-            framework->serviceListeners = NULL;
-            arrayList_create(framework->mp, &framework->serviceListeners);
-            framework->bundleListeners = NULL;
-            arrayList_create(framework->mp, &framework->bundleListeners);
-            framework->requests = NULL;
-            arrayList_create(framework->mp, &framework->requests);
-
             framework_releaseBundleLock(framework, framework->bundle);
 
             status = CELIX_SUCCESS;
@@ -499,7 +528,8 @@ celix_status_t framework_start(framework
 	bundle_state_e state;
 
 	if (lock != CELIX_SUCCESS) {
-		printf("could not get lock\n");
+		fw_log(NULL, FW_LOG_ERROR,  "Could not lock framework bundle");
+//		fw_fireFrameworkEvent(framework, FRAMEWORK_EVENT_ERROR, framework->bundle, lock, "Could not lock framework bundle");
 		framework_releaseBundleLock(framework, framework->bundle);
 		return lock;
 	}
@@ -518,6 +548,9 @@ celix_status_t framework_start(framework
 
 	framework_releaseBundleLock(framework, framework->bundle);
 
+	fw_fireBundleEvent(framework, BUNDLE_EVENT_STARTED, framework->bundle);
+	fw_fireFrameworkEvent(framework, FRAMEWORK_EVENT_STARTED, framework->bundle, 0, NULL);
+
 	return CELIX_SUCCESS;
 }
 
@@ -529,7 +562,10 @@ celix_status_t fw_getProperty(framework_
 	celix_status_t status = CELIX_SUCCESS;
 
 	if (framework == NULL || name == NULL || *value != NULL) {
+		char errMsg[256];
 		status = CELIX_ILLEGAL_ARGUMENT;
+		celix_strerror(status, errMsg, 256);
+		fw_log(NULL, FW_LOG_ERROR,  errMsg);
 	} else {
 		if (framework->configurationMap != NULL) {
 			*value = properties_get(framework->configurationMap, (char *) name);
@@ -554,13 +590,14 @@ celix_status_t fw_installBundle2(framewo
 
 	celix_status_t status = framework_acquireInstallLock(framework, location);
     if (status != CELIX_SUCCESS) {
+    	fw_log(NULL, FW_LOG_ERROR,  "Could not acquire install lock");
         return status;
     }
 
     bundle_getState(framework->bundle, &state);
 
 	if (state == BUNDLE_STOPPING || state == BUNDLE_UNINSTALLED) {
-		printf("The framework has been shutdown.\n");
+		fw_log(NULL, FW_LOG_INFO,  "The framework is being shutdown");
 		framework_releaseInstallLock(framework, location);
 		return CELIX_FRAMEWORK_SHUTDOWN;
 	}
@@ -577,6 +614,7 @@ celix_status_t fw_installBundle2(framewo
 		status = bundleCache_createArchive(framework->cache, bundlePool, id, location, inputFile, &bundle_archive);
 		if (status != CELIX_SUCCESS) {
 		    framework_releaseInstallLock(framework, location);
+		    fw_log(NULL, FW_LOG_ERROR,  "Could not create bundle archive");
 		    return status;
 		} else {
 		    archive = bundle_archive;
@@ -588,8 +626,8 @@ celix_status_t fw_installBundle2(framewo
 
 	locked = framework_acquireGlobalLock(framework);
 	if (!locked) {
-		printf("Unable to acquire the global lock to install the bundle\n");
 		status = CELIX_BUNDLE_EXCEPTION;
+		fw_log(NULL, FW_LOG_ERROR,  "Unable to acquire the global lock to install the bundle");
 	} else {
 	    status = bundle_createFromArchive(bundle, framework, archive, bundlePool);
 	}
@@ -598,12 +636,16 @@ celix_status_t fw_installBundle2(framewo
 	if (status == CELIX_SUCCESS) {
         hashMap_put(framework->installedBundleMap, location, *bundle);
 	} else {
-	    printf("Unable to install bundle: %s\n", location);
+		char msg[256];
+		sprintf(msg, "Unable to install bundle: %s", location);
+	    fw_log(NULL, FW_LOG_ERROR,  msg);
 	    bundleArchive_closeAndDelete(bundle_archive);
 	    apr_pool_destroy(bundlePool);
 	}
     framework_releaseInstallLock(framework, location);
 
+    fw_fireBundleEvent(framework, BUNDLE_EVENT_INSTALLED, *bundle);
+
   	return status;
 }
 
@@ -681,23 +723,23 @@ celix_status_t fw_startBundle(framework_
 
 	switch (state) {
 		case BUNDLE_UNKNOWN:
-			printf("Cannot start bundle since its state is unknown.");
+			printf("Cannot start bundle since its state is unknown.\n");
 			framework_releaseBundleLock(framework, bundle);
 			return CELIX_ILLEGAL_STATE;
 		case BUNDLE_UNINSTALLED:
-			printf("Cannot start bundle since it is uninstalled.");
+			printf("Cannot start bundle since it is uninstalled.\n");
 			framework_releaseBundleLock(framework, bundle);
 			return CELIX_ILLEGAL_STATE;
 		case BUNDLE_STARTING:
-			printf("Cannot start bundle since it is starting.");
+			printf("Cannot start bundle since it is starting.\n");
 			framework_releaseBundleLock(framework, bundle);
 			return CELIX_BUNDLE_EXCEPTION;
 		case BUNDLE_STOPPING:
-			printf("Cannot start bundle since it is stopping.");
+			printf("Cannot start bundle since it is stopping.\n");
 			framework_releaseBundleLock(framework, bundle);
 			return CELIX_ILLEGAL_STATE;
 		case BUNDLE_ACTIVE:
-			printf("Cannot start bundle since it is already active.");
+			printf("Cannot start bundle since it is already active.\n");
 			framework_releaseBundleLock(framework, bundle);
 			return CELIX_SUCCESS;
 		case BUNDLE_INSTALLED:
@@ -787,7 +829,7 @@ celix_status_t fw_startBundle(framework_
 
                 framework_setBundleStateAndNotify(framework, bundle, BUNDLE_STARTING);
 
-                
+                fw_fireBundleEvent(framework, BUNDLE_EVENT_STARTING, bundle);
 
                 bundle_getContext(bundle, &context);
 
@@ -821,7 +863,7 @@ celix_status_t framework_updateBundle(fr
 	bundle_archive_pt archive = NULL;
 
 	if (lock != CELIX_SUCCESS) {
-		printf("Cannot update bundle, in wrong state");
+		printf("Cannot update bundle, in wrong state\n");
 		framework_releaseBundleLock(framework, bundle);
 		return lock;
 	}
@@ -848,6 +890,9 @@ celix_status_t framework_updateBundle(fr
 	status = bundleArchive_setLastModified(archive, time(NULL));
 	framework_setBundleStateAndNotify(framework, bundle, BUNDLE_INSTALLED);
 
+	fw_fireBundleEvent(framework, BUNDLE_EVENT_UNRESOLVED, bundle);
+	fw_fireBundleEvent(framework, BUNDLE_EVENT_UPDATED, bundle);
+
 	// Refresh packages?
 
 	if (oldState == BUNDLE_ACTIVE) {
@@ -863,7 +908,7 @@ celix_status_t fw_stopBundle(framework_p
 
 	status = framework_acquireBundleLock(framework, bundle, BUNDLE_INSTALLED|BUNDLE_RESOLVED|BUNDLE_STARTING|BUNDLE_ACTIVE);
 	if (status != CELIX_SUCCESS) {
-		printf("Cannot stop bundle");
+		printf("Cannot stop bundle\n");
 		framework_releaseBundleLock(framework, bundle);
 	} else {
 		bundle_state_e state;
@@ -882,19 +927,19 @@ celix_status_t fw_stopBundle(framework_p
 
 		switch (state) {
 			case BUNDLE_UNKNOWN:
-				printf("Cannot stop bundle since its state is unknown.");
+				printf("Cannot stop bundle since its state is unknown.\n");
 				framework_releaseBundleLock(framework, bundle);
 				return CELIX_ILLEGAL_STATE;
 			case BUNDLE_UNINSTALLED:
-				printf("Cannot stop bundle since it is uninstalled.");
+				printf("Cannot stop bundle since it is uninstalled.\n");
 				framework_releaseBundleLock(framework, bundle);
 				return status;
 			case BUNDLE_STARTING:
-				printf("Cannot stop bundle since it is starting.");
+				printf("Cannot stop bundle since it is starting.\n");
 				framework_releaseBundleLock(framework, bundle);
 				return status;
 			case BUNDLE_STOPPING:
-				printf("Cannot stop bundle since it is stopping.");
+				printf("Cannot stop bundle since it is stopping.\n");
 				framework_releaseBundleLock(framework, bundle);
 				return status;
 			case BUNDLE_INSTALLED:
@@ -907,6 +952,7 @@ celix_status_t fw_stopBundle(framework_p
 		}
 
 		framework_setBundleStateAndNotify(framework, bundle, BUNDLE_STOPPING);
+		fw_fireBundleEvent(framework, BUNDLE_EVENT_STOPPING, bundle);
 
 		activator = bundle_getActivator(bundle);
 		
@@ -941,6 +987,8 @@ celix_status_t fw_stopBundle(framework_p
 		framework_setBundleStateAndNotify(framework, bundle, BUNDLE_RESOLVED);
 
 		framework_releaseBundleLock(framework, bundle);
+
+		fw_fireBundleEvent(framework, BUNDLE_EVENT_STOPPED, bundle);
 	}
 
 	return status;
@@ -953,7 +1001,7 @@ celix_status_t fw_uninstallBundle(framew
 
     celix_status_t lock = framework_acquireBundleLock(framework, bundle, BUNDLE_INSTALLED|BUNDLE_RESOLVED|BUNDLE_STARTING|BUNDLE_ACTIVE|BUNDLE_STOPPING);
     if (lock != CELIX_SUCCESS) {
-        printf("Cannot stop bundle");
+        printf("Cannot stop bundle\n");
         framework_releaseBundleLock(framework, bundle);
         bundle_getState(bundle, &state);
         if (state == BUNDLE_UNINSTALLED) {
@@ -1101,6 +1149,7 @@ celix_status_t fw_refreshBundle(framewor
 
         if (fire) {
             framework_setBundleStateAndNotify(framework, bundle, BUNDLE_INSTALLED);
+            fw_fireBundleEvent(framework, BUNDLE_EVENT_UNRESOLVED, bundle);
         }
 
         framework_releaseBundleLock(framework, bundle);
@@ -1458,7 +1507,6 @@ celix_status_t fw_addBundleListener(fram
 	} else {
 		bundleListener->listener = listener;
 		bundleListener->bundle = bundle;
-		bundleListener->pool = pool;
 
 		arrayList_add(framework->bundleListeners, bundleListener);
 	}
@@ -1476,7 +1524,42 @@ celix_status_t fw_removeBundleListener(f
 		bundleListener = (fw_bundle_listener_pt) arrayList_get(framework->bundleListeners, i);
 		if (bundleListener->listener == listener && bundleListener->bundle == bundle) {
 			arrayList_remove(framework->bundleListeners, i);
-			apr_pool_destroy(bundleListener->pool);
+		}
+	}
+
+	return status;
+}
+
+celix_status_t fw_addFrameworkListener(framework_pt framework, bundle_pt bundle, framework_listener_pt listener) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	apr_pool_t *pool = NULL;
+	fw_framework_listener_pt frameworkListener = NULL;
+
+	apr_pool_create(&pool, framework->mp);
+	frameworkListener = (fw_framework_listener_pt) apr_palloc(pool, sizeof(*frameworkListener));
+	if (!frameworkListener) {
+		status = CELIX_ENOMEM;
+	} else {
+		frameworkListener->listener = listener;
+		frameworkListener->bundle = bundle;
+
+		arrayList_add(framework->frameworkListeners, frameworkListener);
+	}
+
+	return status;
+}
+
+celix_status_t fw_removeFrameworkListener(framework_pt framework, bundle_pt bundle, framework_listener_pt listener) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	unsigned int i;
+	fw_framework_listener_pt frameworkListener;
+
+	for (i = 0; i < arrayList_size(framework->frameworkListeners); i++) {
+		frameworkListener = (fw_framework_listener_pt) arrayList_get(framework->frameworkListeners, i);
+		if (frameworkListener->listener == listener && frameworkListener->bundle == bundle) {
+			arrayList_remove(framework->frameworkListeners, i);
 		}
 	}
 
@@ -1686,20 +1769,20 @@ celix_status_t framework_setBundleStateA
 
 	int err = apr_thread_mutex_lock(framework->bundleLock);
 	if (err != 0) {
-		celix_log("Failed to lock");
+		fw_log(NULL, FW_LOG_ERROR,  "Failed to lock");
 		return CELIX_BUNDLE_EXCEPTION;
 	}
 
 	bundle_setState(bundle, state);
 	err = apr_thread_cond_broadcast(framework->condition);
 	if (err != 0) {
-		celix_log("Failed to broadcast");
+		fw_log(NULL, FW_LOG_ERROR,  "Failed to broadcast");
 		ret = CELIX_BUNDLE_EXCEPTION;
 	}
 
 	err = apr_thread_mutex_unlock(framework->bundleLock);
 	if (err != 0) {
-		celix_log("Failed to unlock");
+		fw_log(NULL, FW_LOG_ERROR,  "Failed to unlock");
 		return CELIX_BUNDLE_EXCEPTION;
 	}
 	return CELIX_SUCCESS;
@@ -1713,7 +1796,7 @@ celix_status_t framework_acquireBundleLo
 
 	int err = apr_thread_mutex_lock(framework->bundleLock);
 	if (err != APR_SUCCESS) {
-		celix_log("Failed to lock");
+		fw_log(NULL, FW_LOG_ERROR,  "Failed to lock");
 		status = CELIX_BUNDLE_EXCEPTION;
 	} else {
 		bool lockable = false;
@@ -1825,7 +1908,7 @@ bool framework_acquireGlobalLock(framewo
 celix_status_t framework_releaseGlobalLock(framework_pt framework) {
 	int ret = CELIX_SUCCESS;
 	if (apr_thread_mutex_lock(framework->bundleLock) != 0) {
-		celix_log("Error locking framework bundle lock");
+		fw_log(NULL, FW_LOG_ERROR,  "Error locking framework bundle lock");
 		return CELIX_FRAMEWORK_EXCEPTION;
 	}
 
@@ -1834,7 +1917,7 @@ celix_status_t framework_releaseGlobalLo
 		if (framework->globalLockCount == 0) {
 			framework->globalLockThread = 0;
 			if (apr_thread_cond_broadcast(framework->condition) != 0) {
-				celix_log("Failed to broadcast global lock release.");
+				fw_log(NULL, FW_LOG_ERROR,  "Failed to broadcast global lock release.");
 				ret = CELIX_FRAMEWORK_EXCEPTION;
 				// still need to unlock before returning
 			}
@@ -1844,7 +1927,7 @@ celix_status_t framework_releaseGlobalLo
 	}
 
 	if (apr_thread_mutex_unlock(framework->bundleLock) != 0) {
-		celix_log("Error unlocking framework bundle lock");
+		fw_log(NULL, FW_LOG_ERROR,  "Error unlocking framework bundle lock");
 		return CELIX_FRAMEWORK_EXCEPTION;
 	}
 	return ret;
@@ -1852,19 +1935,19 @@ celix_status_t framework_releaseGlobalLo
 
 celix_status_t framework_waitForStop(framework_pt framework) {
 	if (apr_thread_mutex_lock(framework->mutex) != 0) {
-		celix_log("Error locking the framework, shutdown gate not set.");
+		fw_log(NULL, FW_LOG_ERROR,  "Error locking the framework, shutdown gate not set.");
 		return CELIX_FRAMEWORK_EXCEPTION;
 	}
 	while (!framework->shutdown) {
 		apr_status_t apr_status = apr_thread_cond_wait(framework->shutdownGate, framework->mutex);
 		printf("FRAMEWORK: Gate opened\n");
 		if (apr_status != 0) {
-			celix_log("Error waiting for shutdown gate.");
+			fw_log(NULL, FW_LOG_ERROR,  "Error waiting for shutdown gate.");
 			return CELIX_FRAMEWORK_EXCEPTION;
 		}
 	}
 	if (apr_thread_mutex_unlock(framework->mutex) != 0) {
-		celix_log("Error unlocking the framework.");
+		fw_log(NULL, FW_LOG_ERROR,  "Error unlocking the framework.");
 		return CELIX_FRAMEWORK_EXCEPTION;
 	}
 	printf("FRAMEWORK: Successful shutdown\n");
@@ -1897,7 +1980,7 @@ static void *APR_THREAD_FUNC framework_s
 
 	err = apr_thread_mutex_lock(fw->mutex);
 	if (err != 0) {
-		celix_log("Error locking the framework, cannot exit clean.");
+		fw_log(NULL, FW_LOG_ERROR,  "Error locking the framework, cannot exit clean.");
 		apr_thread_exit(thd, APR_ENOLOCK);
 		return NULL;
 	}
@@ -1908,10 +1991,10 @@ static void *APR_THREAD_FUNC framework_s
 	printf("FRAMEWORK: BC send\n");
 	if (err != 0) {
 		printf("FRAMEWORK: BC send\n");
-		celix_log("Error waking the shutdown gate, cannot exit clean.");
+		fw_log(NULL, FW_LOG_ERROR,  "Error waking the shutdown gate, cannot exit clean.");
 		err = apr_thread_mutex_unlock(fw->mutex);
 		if (err != 0) {
-			celix_log("Error unlocking the framework, cannot exit clean.");
+			fw_log(NULL, FW_LOG_ERROR,  "Error unlocking the framework, cannot exit clean.");
 		}
 
 		apr_thread_exit(thd, APR_ENOLOCK);
@@ -1920,7 +2003,7 @@ static void *APR_THREAD_FUNC framework_s
 	printf("FRAMEWORK: Unlock\n");
 	err = apr_thread_mutex_unlock(fw->mutex);
 	if (err != 0) {
-		celix_log("Error unlocking the framework, cannot exit clean.");
+		fw_log(NULL, FW_LOG_ERROR,  "Error unlocking the framework, cannot exit clean.");
 	}
 
 	printf("FRAMEWORK: Exit thread\n");
@@ -1958,6 +2041,7 @@ celix_status_t fw_fireBundleEvent(framew
 			request->filter = NULL;
 			request->listeners = framework->bundleListeners;
 			request->type = BUNDLE_EVENT_TYPE;
+			request->error = NULL;
 
 			arrayList_add(framework->requests, request);
 			if (apr_thread_mutex_lock(framework->dispatcherLock) != APR_SUCCESS) {
@@ -1977,6 +2061,38 @@ celix_status_t fw_fireBundleEvent(framew
 	return status;
 }
 
+celix_status_t fw_fireFrameworkEvent(framework_pt framework, framework_event_type_e eventType, bundle_pt bundle, celix_status_t errorCode, char *error) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	request_pt request = (request_pt) malloc(sizeof(*request));
+	if (!request) {
+		status = CELIX_ENOMEM;
+	} else {
+		request->bundle = bundle;
+		request->eventType = eventType;
+		request->filter = NULL;
+		request->listeners = framework->frameworkListeners;
+		request->type = FRAMEWORK_EVENT_TYPE;
+		request->errorCode = errorCode;
+		request->error = error;
+
+		arrayList_add(framework->requests, request);
+		if (apr_thread_mutex_lock(framework->dispatcherLock) != APR_SUCCESS) {
+			status = CELIX_FRAMEWORK_EXCEPTION;
+		} else {
+			if (apr_thread_cond_broadcast(framework->dispatcher)) {
+				status = CELIX_FRAMEWORK_EXCEPTION;
+			} else {
+				if (apr_thread_mutex_unlock(framework->dispatcherLock)) {
+					status = CELIX_FRAMEWORK_EXCEPTION;
+				}
+			}
+		}
+	}
+
+	return status;
+}
+
 static void *APR_THREAD_FUNC fw_eventDispatcher(apr_thread_t *thd, void *fw) {
 	framework_pt framework = (framework_pt) fw;
 	request_pt request = NULL;
@@ -1986,7 +2102,7 @@ static void *APR_THREAD_FUNC fw_eventDis
 		apr_status_t status;
 
 		if (apr_thread_mutex_lock(framework->dispatcherLock) != 0) {
-			celix_log("Error locking the dispatcher");
+			fw_log(NULL, FW_LOG_ERROR,  "Error locking the dispatcher");
 			return NULL;
 		}
 
@@ -2005,7 +2121,7 @@ static void *APR_THREAD_FUNC fw_eventDis
 		request = (request_pt) arrayList_remove(framework->requests, 0);
 
 		if ((status = apr_thread_mutex_unlock(framework->dispatcherLock)) != 0) {
-			celix_log("Error unlocking the dispatcher.");
+			fw_log(NULL, FW_LOG_ERROR,  "Error unlocking the dispatcher.");
 			apr_thread_exit(thd, status);
 			return NULL;
 		}
@@ -2021,6 +2137,15 @@ static void *APR_THREAD_FUNC fw_eventDis
 					event->type = request->eventType;
 
 					fw_invokeBundleListener(framework, listener->listener, event, listener->bundle);
+				} else if (request->type == FRAMEWORK_EVENT_TYPE) {
+					fw_framework_listener_pt listener = (fw_framework_listener_pt) arrayList_get(request->listeners, i);
+					framework_event_pt event = (framework_event_pt) apr_palloc(listener->listener->pool, sizeof(*event));
+					event->bundle = request->bundle;
+					event->type = request->eventType;
+					event->error = request->error;
+					event->errorCode = request->errorCode;
+
+					fw_invokeFrameworkListener(framework, listener->listener, event, listener->bundle);
 				}
 			}
 		}
@@ -2044,6 +2169,16 @@ celix_status_t fw_invokeBundleListener(f
 	return CELIX_SUCCESS;
 }
 
+celix_status_t fw_invokeFrameworkListener(framework_pt framework, framework_listener_pt listener, framework_event_pt event, bundle_pt bundle) {
+	bundle_state_e state;
+	bundle_getState(bundle, &state);
+	if (state == BUNDLE_STARTING || state == BUNDLE_ACTIVE) {
+		listener->frameworkEvent(listener, event);
+	}
+
+	return CELIX_SUCCESS;
+}
+
 celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
 	// nothing to do
 	return CELIX_SUCCESS;
@@ -2061,7 +2196,7 @@ celix_status_t bundleActivator_stop(void
 	    if (apr_thread_create(&shutdownThread, NULL, framework_shutdown, framework, framework->mp) == APR_SUCCESS) {
             apr_thread_detach(shutdownThread);
 	    } else {
-            celix_log("Could not create shutdown thread, normal exit not possible.");
+            fw_log(NULL, FW_LOG_ERROR,  "Could not create shutdown thread, normal exit not possible.");
 	        status = CELIX_FRAMEWORK_EXCEPTION;
 	    }
 	} else {

Modified: incubator/celix/trunk/framework/public/include/bundle_context.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/framework/public/include/bundle_context.h?rev=1543331&r1=1543330&r2=1543331&view=diff
==============================================================================
--- incubator/celix/trunk/framework/public/include/bundle_context.h (original)
+++ incubator/celix/trunk/framework/public/include/bundle_context.h Tue Nov 19 07:38:30 2013
@@ -37,6 +37,7 @@ typedef struct bundleContext *bundle_con
 #include "service_factory.h"
 #include "service_listener.h"
 #include "bundle_listener.h"
+#include "framework_listener.h"
 #include "properties.h"
 #include "array_list.h"
 
@@ -70,6 +71,9 @@ FRAMEWORK_EXPORT celix_status_t bundleCo
 FRAMEWORK_EXPORT celix_status_t bundleContext_addBundleListener(bundle_context_pt context, bundle_listener_pt listener);
 FRAMEWORK_EXPORT celix_status_t bundleContext_removeBundleListener(bundle_context_pt context, bundle_listener_pt listener);
 
+FRAMEWORK_EXPORT celix_status_t bundleContext_addFrameworkListener(bundle_context_pt context, framework_listener_pt listener);
+FRAMEWORK_EXPORT celix_status_t bundleContext_removeFrameworkListener(bundle_context_pt context, framework_listener_pt listener);
+
 FRAMEWORK_EXPORT celix_status_t bundleContext_getProperty(bundle_context_pt context, const char *name, char **value);
 
 #endif /* BUNDLE_CONTEXT_H_ */

Modified: incubator/celix/trunk/framework/public/include/celix_log.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/framework/public/include/celix_log.h?rev=1543331&r1=1543330&r2=1543331&view=diff
==============================================================================
--- incubator/celix/trunk/framework/public/include/celix_log.h (original)
+++ incubator/celix/trunk/framework/public/include/celix_log.h Tue Nov 19 07:38:30 2013
@@ -28,11 +28,25 @@
 #define CELIX_LOG_H_
 
 #include <stdio.h>
+#include "framework.h"
 
 #if defined(WIN32)
 #define celix_log(msg) printf("%s\n", msg);
 #else
 #define celix_log(msg) printf("%s\n\tat %s(%s:%d)\n", msg, __func__, __FILE__, __LINE__);
+#define fw_log(framework, level, fmsg, args...) framework_log(framework, level, __func__, __FILE__, __LINE__, fmsg, ## args)
 #endif
 
+enum framework_log_level
+{
+    FW_LOG_ERROR = 0x00000001,
+    FW_LOG_WARNING = 0x00000002,
+    FW_LOG_INFO = 0x00000003,
+    FW_LOG_DEBUG = 0x00000004,
+};
+
+typedef enum framework_log_level framework_log_level_t;
+
+void framework_log(framework_pt framework, framework_log_level_t level, const char *func, const char *file, int line, char *fmsg, ...);
+
 #endif /* CELIX_LOG_H_ */

Copied: incubator/celix/trunk/framework/public/include/framework_event.h (from r1543326, incubator/celix/trunk/deployment_admin/private/src/log.c)
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/framework/public/include/framework_event.h?p2=incubator/celix/trunk/framework/public/include/framework_event.h&p1=incubator/celix/trunk/deployment_admin/private/src/log.c&r1=1543326&r2=1543331&rev=1543331&view=diff
==============================================================================
--- incubator/celix/trunk/deployment_admin/private/src/log.c (original)
+++ incubator/celix/trunk/framework/public/include/framework_event.h Tue Nov 19 07:38:30 2013
@@ -1,4 +1,4 @@
-/**
+/*
  *Licensed to the Apache Software Foundation (ASF) under one
  *or more contributor license agreements.  See the NOTICE file
  *distributed with this work for additional information
@@ -17,44 +17,41 @@
  *under the License.
  */
 /*
- * log.c
+ * framework_event.h
  *
- *  \date       Apr 19, 2012
+ *  \date       Oct 8, 2013
  *  \author    	<a href="mailto:celix-dev@incubator.apache.org">Apache Celix Project Team</a>
  *  \copyright	Apache License, Version 2.0
  */
 
-#include <stddef.h>
-#include <apr_general.h>
-
-#include "celix_errno.h"
+#ifndef FRAMEWORK_EVENT_H_
+#define FRAMEWORK_EVENT_H_
 
-#include "log.h"
-#include "log_store.h"
-
-struct log {
-	log_store_pt logStore;
+enum framework_event_type
+{
+	FRAMEWORK_EVENT_STARTED = 0x00000001,
+	FRAMEWORK_EVENT_ERROR = 0x00000002,
+	FRAMEWORK_EVENT_PACKAGES_REFRESHED = 0x00000004,
+	FRAMEWORK_EVENT_STARTLEVEL_CHANGED = 0x00000008,
+	FRAMEWORK_EVENT_WARNING = 0x00000010,
+	FRAMEWORK_EVENT_INFO = 0x00000020,
+	FRAMEWORK_EVENT_STOPPED = 0x00000040,
+	FRAMEWORK_EVENT_STOPPED_UPDATE = 0x00000080,
+	FRAMEWORK_EVENT_STOPPED_BOOTCLASSPATH_MODIFIED = 0x00000100,
+	FRAMEWORK_EVENT_WAIT_TIMEDOUT = 0x00000200,
 };
 
-celix_status_t log_create(apr_pool_t *pool, log_store_pt store, log_pt *log) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	*log = apr_palloc(pool, sizeof(**log));
-	if (!*log) {
-		status = CELIX_ENOMEM;
-	} else {
-		(*log)->logStore = store;
-	}
+typedef enum framework_event_type framework_event_type_e;
+typedef struct framework_event *framework_event_pt;
 
-	return status;
-}
+#include "service_reference.h"
+#include "bundle.h"
 
-celix_status_t log_log(log_pt log, unsigned int type, properties_pt properties) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	log_event_pt event = NULL;
-
-	status = logStore_put(log->logStore, type, properties, &event);
+struct framework_event {
+	bundle_pt bundle;
+	framework_event_type_e type;
+	celix_status_t errorCode;
+	char *error;
+};
 
-	return status;
-}
+#endif /* FRAMEWORK_EVENT_H_ */

Copied: incubator/celix/trunk/framework/public/include/framework_listener.h (from r1543326, incubator/celix/trunk/deployment_admin/private/include/log.h)
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/framework/public/include/framework_listener.h?p2=incubator/celix/trunk/framework/public/include/framework_listener.h&p1=incubator/celix/trunk/deployment_admin/private/include/log.h&r1=1543326&r2=1543331&rev=1543331&view=diff
==============================================================================
--- incubator/celix/trunk/deployment_admin/private/include/log.h (original)
+++ incubator/celix/trunk/framework/public/include/framework_listener.h Tue Nov 19 07:38:30 2013
@@ -1,4 +1,4 @@
-/**
+/*
  *Licensed to the Apache Software Foundation (ASF) under one
  *or more contributor license agreements.  See the NOTICE file
  *distributed with this work for additional information
@@ -16,25 +16,36 @@
  *specific language governing permissions and limitations
  *under the License.
  */
-/*
- * log.h
+/**
+ *
+ * @defgroup FrameworkListener Framework Listener
+ * @ingroup framework
+ * @{
  *
- *  \date       Apr 18, 2012
  *  \author    	<a href="mailto:celix-dev@incubator.apache.org">Apache Celix Project Team</a>
+ *  \date      	Oct 8, 2013
  *  \copyright	Apache License, Version 2.0
  */
-
-#ifndef LOG_H_
-#define LOG_H_
+#ifndef FRAMEWORK_LISTENER_H_
+#define FRAMEWORK_LISTENER_H_
 
 #include <apr_general.h>
 
-#include "log_event.h"
-#include "log_store.h"
+typedef struct framework_listener *framework_listener_pt;
 
-typedef struct log *log_pt;
+#include "celix_errno.h"
+#include "framework_event.h"
 
-celix_status_t log_create(apr_pool_t *pool, log_store_pt store, log_pt *log);
-celix_status_t log_log(log_pt log, unsigned int type, properties_pt properties);
+struct framework_listener {
+	apr_pool_t *pool;
+	void * handle;
+	celix_status_t (*frameworkEvent)(void * listener, framework_event_pt event);
+};
 
-#endif /* LOG_H_ */
+
+
+#endif /* FRAMEWORK_LISTENER_H_ */
+
+/**
+ * @}
+ */

Modified: incubator/celix/trunk/launcher/private/src/launcher.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/launcher/private/src/launcher.c?rev=1543331&r1=1543330&r2=1543331&view=diff
==============================================================================
--- incubator/celix/trunk/launcher/private/src/launcher.c (original)
+++ incubator/celix/trunk/launcher/private/src/launcher.c Tue Nov 19 07:38:30 2013
@@ -68,68 +68,73 @@ int main(void) {
     config = properties_load("config.properties");
     autoStart = properties_get(config, "cosgi.auto.start.1");
     framework = NULL;
-    framework_create(&framework, memoryPool, config);
-    fw_init(framework);
-
-    // Start the system bundle
-    framework_getFrameworkBundle(framework, &fwBundle);
-    bundle_start(fwBundle);
-
-    if (apr_pool_create(&pool, memoryPool) == APR_SUCCESS) {
-		char delims[] = " ";
-		char *result = NULL;	
-        linked_list_pt bundles;
-		array_list_pt installed = NULL;
-		bundle_pt bundle = NULL;
-		bundle_context_pt context = NULL;
-		linked_list_iterator_pt iter = NULL;
-		unsigned int i;
-
-        linkedList_create(pool, &bundles);
-        result = strtok(autoStart, delims);
-        while (result != NULL) {
-            char * location = apr_pstrdup(memoryPool, result);
-            linkedList_addElement(bundles, location);
-            result = strtok(NULL, delims);
-        }
-        // First install all bundles
-        // Afterwards start them
-        arrayList_create(pool, &installed);
-        framework_getFrameworkBundle(framework, &bundle);
-        bundle_getContext(bundle, &context);
-        iter = linkedListIterator_create(bundles, 0);
-        while (linkedListIterator_hasNext(iter)) {
-            bundle_pt current = NULL;
-            char * location = (char *) linkedListIterator_next(iter);
-            if (bundleContext_installBundle(context, location, &current) == CELIX_SUCCESS) {
-                // Only add bundle if it is installed correctly
-                arrayList_add(installed, current);
-            } else {
-                char error[256];
-                sprintf(error, "Could not install bundle from %s", location);
-                celix_log(error);
-            }
-            linkedListIterator_remove(iter);
-        }
-        linkedListIterator_destroy(iter);
-
-        for (i = 0; i < arrayList_size(installed); i++) {
-            bundle_pt bundle = (bundle_pt) arrayList_get(installed, i);
-            bundle_startWithOptions(bundle, 0);
-        }
-
-        arrayList_destroy(installed);
-        apr_pool_destroy(pool);
+    celix_status_t status = framework_create(&framework, memoryPool, config);
+    if (status == CELIX_SUCCESS) {
+		fw_init(framework);
+
+		// Start the system bundle
+		framework_getFrameworkBundle(framework, &fwBundle);
+		bundle_start(fwBundle);
+
+		if (apr_pool_create(&pool, memoryPool) == APR_SUCCESS) {
+			char delims[] = " ";
+			char *result = NULL;
+			linked_list_pt bundles;
+			array_list_pt installed = NULL;
+			bundle_pt bundle = NULL;
+			bundle_context_pt context = NULL;
+			linked_list_iterator_pt iter = NULL;
+			unsigned int i;
+
+			linkedList_create(pool, &bundles);
+			result = strtok(autoStart, delims);
+			while (result != NULL) {
+				char * location = apr_pstrdup(memoryPool, result);
+				linkedList_addElement(bundles, location);
+				result = strtok(NULL, delims);
+			}
+			// First install all bundles
+			// Afterwards start them
+			arrayList_create(pool, &installed);
+			framework_getFrameworkBundle(framework, &bundle);
+			bundle_getContext(bundle, &context);
+			iter = linkedListIterator_create(bundles, 0);
+			while (linkedListIterator_hasNext(iter)) {
+				bundle_pt current = NULL;
+				char * location = (char *) linkedListIterator_next(iter);
+				if (bundleContext_installBundle(context, location, &current) == CELIX_SUCCESS) {
+					// Only add bundle if it is installed correctly
+					arrayList_add(installed, current);
+				} else {
+					char error[256];
+					sprintf(error, "Could not install bundle from %s", location);
+					celix_log(error);
+				}
+				linkedListIterator_remove(iter);
+			}
+			linkedListIterator_destroy(iter);
+
+			for (i = 0; i < arrayList_size(installed); i++) {
+				bundle_pt bundle = (bundle_pt) arrayList_get(installed, i);
+				bundle_startWithOptions(bundle, 0);
+			}
+
+			arrayList_destroy(installed);
+			apr_pool_destroy(pool);
+		}
+
+		framework_waitForStop(framework);
+		framework_destroy(framework);
+		properties_destroy(config);
+    } else {
+    	celix_log("Problem creating framework");
     }
 
-    framework_waitForStop(framework);
-    framework_destroy(framework);
-    properties_destroy(config);
+	apr_pool_destroy(memoryPool);
+	apr_terminate();
 
-    apr_pool_destroy(memoryPool);
-    apr_terminate();
+	printf("LAUNCHER: Exit\n");
 
-    printf("LAUNCHER: Exit\n");
     return 0;
 }
 

Modified: incubator/celix/trunk/log_service/private/include/log.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/log_service/private/include/log.h?rev=1543331&r1=1543330&r2=1543331&view=diff
==============================================================================
--- incubator/celix/trunk/log_service/private/include/log.h (original)
+++ incubator/celix/trunk/log_service/private/include/log.h Tue Nov 19 07:38:30 2013
@@ -39,6 +39,9 @@ celix_status_t log_create(apr_pool_t *po
 celix_status_t log_addEntry(log_pt log, log_entry_pt entry);
 celix_status_t log_getEntries(log_pt log, apr_pool_t *memory_pool, linked_list_pt *list);
 
+celix_status_t log_bundleChanged(void *listener, bundle_event_pt event);
+celix_status_t log_frameworkEvent(void *listener, framework_event_pt event);
+
 celix_status_t log_addLogListener(log_pt logger, log_listener_pt listener);
 celix_status_t log_removeLogListener(log_pt logger, log_listener_pt listener);
 celix_status_t log_removeAllLogListener(log_pt logger);

Modified: incubator/celix/trunk/log_service/private/src/log.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/log_service/private/src/log.c?rev=1543331&r1=1543330&r2=1543331&view=diff
==============================================================================
--- incubator/celix/trunk/log_service/private/src/log.c (original)
+++ incubator/celix/trunk/log_service/private/src/log.c Tue Nov 19 07:38:30 2013
@@ -145,6 +145,56 @@ celix_status_t log_getEntries(log_pt log
     }
 }
 
+celix_status_t log_bundleChanged(void *listener, bundle_event_pt event) {
+	celix_status_t status = CELIX_SUCCESS;
+	log_pt logger = ((bundle_listener_pt) listener)->handle;
+	log_entry_pt entry = NULL;
+
+	int messagesLength = 10;
+	char *messages[] = {
+		"BUNDLE_EVENT_INSTALLED",
+		"BUNDLE_EVENT_STARTED",
+		"BUNDLE_EVENT_STOPPED",
+		"BUNDLE_EVENT_UPDATED",
+		"BUNDLE_EVENT_UNINSTALLED",
+		"BUNDLE_EVENT_RESOLVED",
+		"BUNDLE_EVENT_UNRESOLVED",
+		"BUNDLE_EVENT_STARTING",
+		"BUNDLE_EVENT_STOPPING",
+		"BUNDLE_EVENT_LAZY_ACTIVATION"
+	};
+
+	char *message = NULL;
+	int i = 0;
+	for (i = 0; i < messagesLength; i++) {
+		if (event->type >> i == 1) {
+			message = messages[i];
+		}
+	}
+
+	if (message != NULL) {
+		status = logEntry_create(event->bundle, NULL, LOG_INFO, message, 0, logger->pool, &entry);
+		if (status == CELIX_SUCCESS) {
+			status = log_addEntry(logger, entry);
+		}
+	}
+
+	return status;
+}
+
+celix_status_t log_frameworkEvent(void *listener, framework_event_pt event) {
+	celix_status_t status = CELIX_SUCCESS;
+	log_pt logger = ((framework_listener_pt) listener)->handle;
+	log_entry_pt entry = NULL;
+
+	status = logEntry_create(event->bundle, NULL, (event->type == FRAMEWORK_EVENT_ERROR) ? LOG_ERROR : LOG_INFO, event->error, event->errorCode, logger->pool, &entry);
+	if (status == CELIX_SUCCESS) {
+		status = log_addEntry(logger, entry);
+	}
+
+	return status;
+}
+
 celix_status_t log_addLogListener(log_pt logger, log_listener_pt listener) {
     celix_status_t status = CELIX_SUCCESS;
     apr_status_t apr_status;

Modified: incubator/celix/trunk/log_service/private/src/log_service_activator.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/log_service/private/src/log_service_activator.c?rev=1543331&r1=1543330&r2=1543331&view=diff
==============================================================================
--- incubator/celix/trunk/log_service/private/src/log_service_activator.c (original)
+++ incubator/celix/trunk/log_service/private/src/log_service_activator.c Tue Nov 19 07:38:30 2013
@@ -39,6 +39,9 @@ struct logActivator {
     service_registration_pt logServiceFactoryReg;
     service_registration_pt logReaderServiceReg;
 
+    bundle_listener_pt bundleListener;
+    framework_listener_pt frameworkListener;
+
 };
 
 celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
@@ -75,6 +78,20 @@ celix_status_t bundleActivator_start(voi
     bundleContext_getMemoryPool(context, &mp);
 
     log_create(mp, &logger);
+
+    // Add logger as Bundle- and FrameworkEvent listener
+    activator->bundleListener = apr_palloc(mp, sizeof(*activator->bundleListener));
+    activator->bundleListener->pool = mp;
+    activator->bundleListener->handle = logger;
+    activator->bundleListener->bundleChanged = log_bundleChanged;
+    bundleContext_addBundleListener(context, activator->bundleListener);
+
+    activator->frameworkListener = apr_palloc(mp, sizeof(*activator->frameworkListener));
+    activator->frameworkListener->pool = mp;
+    activator->frameworkListener->handle = logger;
+    activator->frameworkListener->frameworkEvent = log_frameworkEvent;
+    bundleContext_addFrameworkListener(context, activator->frameworkListener);
+
     logFactory_create(mp, logger, &factory);
 
     bundleContext_registerServiceFactory(context, (char *) LOG_SERVICE_NAME, factory, NULL, &activator->logServiceFactoryReg);
@@ -101,6 +118,9 @@ celix_status_t bundleActivator_stop(void
 	serviceRegistration_unregister(activator->logServiceFactoryReg);
 	activator->logServiceFactoryReg = NULL;
 
+	bundleContext_removeBundleListener(context, activator->bundleListener);
+	bundleContext_removeFrameworkListener(context, activator->frameworkListener);
+
     return CELIX_SUCCESS;
 }
 

Modified: incubator/celix/trunk/shell/private/src/log_command.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/shell/private/src/log_command.c?rev=1543331&r1=1543330&r2=1543331&view=diff
==============================================================================
--- incubator/celix/trunk/shell/private/src/log_command.c (original)
+++ incubator/celix/trunk/shell/private/src/log_command.c Tue Nov 19 07:38:30 2013
@@ -34,6 +34,7 @@
 #include "linked_list_iterator.h"
 
 void logCommand_execute(command_pt command, char *line, void (*out)(char *), void (*err)(char *));
+celix_status_t logCommand_levelAsString(command_pt command, log_level_t level, char **string);
 
 command_pt logCommand_create(bundle_context_pt context) {
     command_pt command = (command_pt) malloc(sizeof(*command));
@@ -70,8 +71,28 @@ void logCommand_execute(command_pt comma
             iter = linkedListIterator_create(list, 0);
             while (linkedListIterator_hasNext(iter)) {
                 log_entry_pt entry = linkedListIterator_next(iter);
-                sprintf(line, "%s\n", entry->message);
-                out(line);
+                char time[20];
+                char *level = NULL;
+                module_pt module = NULL;
+                char *bundleSymbolicName = NULL;
+                char errorString[256];
+
+				celix_status_t status = bundle_getCurrentModule(entry->bundle, &module);
+				if (status == CELIX_SUCCESS) {
+					status = module_getSymbolicName(module, &bundleSymbolicName);
+
+					strftime(time, 20, "%Y-%m-%d %H:%M:%S", localtime(&entry->time));
+					logCommand_levelAsString(command, entry->level, &level);
+
+					if (entry->errorCode > 0) {
+						celix_strerror(entry->errorCode, errorString, 256);
+						sprintf(line, "%s - Bundle: %s - %s - %d %s\n", time, bundleSymbolicName, entry->message, entry->errorCode, errorString);
+						out(line);
+					} else {
+						sprintf(line, "%s - Bundle: %s - %s\n", time, bundleSymbolicName, entry->message);
+						out(line);
+					}
+				}
             }
             apr_pool_destroy(memory_pool);
         } else {
@@ -81,3 +102,23 @@ void logCommand_execute(command_pt comma
         out("No log reader available\n");
     }
 }
+
+celix_status_t logCommand_levelAsString(command_pt command, log_level_t level, char **string) {
+	switch (level) {
+	case LOG_ERROR:
+		*string = "ERROR";
+		break;
+	case LOG_WARNING:
+		*string = "WARNING";
+		break;
+	case LOG_INFO:
+		*string = "INFO";
+		break;
+	case LOG_DEBUG:
+	default:
+		*string = "DEBUG";
+		break;
+	}
+
+	return CELIX_SUCCESS;
+}