mirror of
				https://github.com/Telecominfraproject/wlan-ap.git
				synced 2025-10-31 02:17:58 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			139 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			139 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From b24a5a890ccd19b0f1b50340c79c5087f08d9447 Mon Sep 17 00:00:00 2001
 | |
| From: John Crispin <john@phrozen.org>
 | |
| Date: Fri, 4 Mar 2022 15:56:30 +0100
 | |
| Subject: [PATCH] ulog: add ringbuffer and log_event notification
 | |
| 
 | |
| Signed-off-by: John Crispin <john@phrozen.org>
 | |
| ---
 | |
|  ucode.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 | |
|  1 file changed, 73 insertions(+), 2 deletions(-)
 | |
| 
 | |
| diff --git a/ucode.c b/ucode.c
 | |
| index cef50e2..9e0373a 100644
 | |
| --- a/ucode.c
 | |
| +++ b/ucode.c
 | |
| @@ -31,6 +31,17 @@ static const char *exception_types[] = {
 | |
|  	[EXCEPTION_EXIT] = "Exit"
 | |
|  };
 | |
|  
 | |
| +struct log_buffer {
 | |
| +	struct list_head list;
 | |
| +	int severity;
 | |
| +	char entry[];
 | |
| +};
 | |
| +
 | |
| +static LIST_HEAD(log_buffer);
 | |
| +static int log_count;
 | |
| +static int log_max = 100;
 | |
| +static uc_value_t *log_event;
 | |
| +
 | |
|  static void
 | |
|  ucode_handle_exception(uc_vm_t *vm, uc_exception_t *ex)
 | |
|  {
 | |
| @@ -287,6 +298,7 @@ static uc_value_t *
 | |
|  uc_ulog(uc_vm_t *vm, size_t nargs, int severity)
 | |
|  {
 | |
|  	uc_value_t *res;
 | |
| +	char *entry;
 | |
|  
 | |
|  	if (!fmtfn) {
 | |
|  		fmtfn = (uc_cfunction_t *)ucv_object_get(uc_vm_scope_get(vm), "sprintf", NULL);
 | |
| @@ -300,7 +312,37 @@ uc_ulog(uc_vm_t *vm, size_t nargs, int severity)
 | |
|  	if (!res)
 | |
|  		return ucv_int64_new(-1);
 | |
|  
 | |
| -	ulog(severity, "%s", ucv_string_get(res));
 | |
| +	entry = ucv_string_get(res);
 | |
| +
 | |
| +	if (log_max) {
 | |
| +		struct log_buffer *log = calloc(1, sizeof(*log) + strlen(entry) + 1);
 | |
| +
 | |
| +		strcpy(log->entry, entry);
 | |
| +		log->severity = severity;
 | |
| +		list_add_tail(&log->list, &log_buffer);
 | |
| +
 | |
| +		if (log_event) {
 | |
| +			uc_value_t *event = ucv_array_new(vm);
 | |
| +
 | |
| +			ucv_array_push(event, ucv_int64_new(severity));
 | |
| +			ucv_array_push(event, ucv_string_new(entry));
 | |
| +
 | |
| +			uc_vm_stack_push(vm, ucv_get(log_event));
 | |
| +			uc_vm_stack_push(vm, ucv_get(event));
 | |
| +			uc_vm_call(vm, false, 1);
 | |
| +		}
 | |
| +
 | |
| +		if (log_count == log_max) {
 | |
| +			struct log_buffer *first = list_first_entry(&log_buffer, struct log_buffer, list);
 | |
| +
 | |
| +			list_del(&first->list);
 | |
| +			free(first);
 | |
| +		} else {
 | |
| +			log_count++;
 | |
| +		}
 | |
| +	}
 | |
| +
 | |
| +	ulog(severity, "%s", entry);
 | |
|  	ucv_put(res);
 | |
|  
 | |
|  	return ucv_int64_new(0);
 | |
| @@ -330,11 +372,27 @@ uc_ulog_err(uc_vm_t *vm, size_t nargs)
 | |
|  	return uc_ulog(vm, nargs, LOG_ERR);
 | |
|  }
 | |
|  
 | |
| +static uc_value_t *
 | |
| +uc_ulog_dump(uc_vm_t *vm, size_t nargs)
 | |
| +{
 | |
| +	uc_value_t *log = ucv_array_new(vm);
 | |
| +	struct log_buffer *iter;
 | |
| +
 | |
| +	list_for_each_entry(iter, &log_buffer, list) {
 | |
| +		uc_value_t *entry = ucv_array_new(vm);
 | |
| +		ucv_array_push(entry, ucv_int64_new(iter->severity));
 | |
| +		ucv_array_push(entry, ucv_string_new(iter->entry));
 | |
| +		ucv_array_push(log, entry);
 | |
| +	}
 | |
| +
 | |
| +	return log;
 | |
| +}
 | |
| +
 | |
|  static void
 | |
|  ucode_init_ulog(ucrun_ctx_t *ucrun)
 | |
|  {
 | |
|  	uc_value_t *ulog = ucv_object_get(ucrun->scope, "ulog", NULL);
 | |
| -	uc_value_t *identity, *channels;
 | |
| +	uc_value_t *identity, *channels, *logsize;
 | |
|  	int flags = 0, channel;
 | |
|  
 | |
|  	/* make sure the declartion is complete */
 | |
| @@ -365,6 +423,18 @@ ucode_init_ulog(ucrun_ctx_t *ucrun)
 | |
|  			flags |= ULOG_STDIO;
 | |
|  	}
 | |
|  
 | |
| +	/* set the internal ring buffer size */
 | |
| +	logsize = ucv_object_get(ulog, "channels", NULL);
 | |
| +	if (ucv_type(logsize) == UC_INTEGER && ucv_int64_get(logsize))
 | |
| +		log_max = ucv_int64_get(logsize);
 | |
| +
 | |
| +	/* find out if ucrun wants a notification when a new log entry is generated */
 | |
| +	log_event = ucv_object_get(ulog, "event", NULL);
 | |
| +	if (ucv_is_callable(log_event))
 | |
| +		ucv_get(log_event);
 | |
| +	else
 | |
| +		log_event = NULL;
 | |
| +
 | |
|  	/* open the log */
 | |
|  	ucrun->ulog_identity = strdup(ucv_string_get(identity));
 | |
|  	ulog_open(flags, LOG_DAEMON, ucrun->ulog_identity);
 | |
| @@ -404,6 +474,7 @@ ucode_init(ucrun_ctx_t *ucrun, int argc, const char **argv, int *rc)
 | |
|  	uc_function_register(ucrun->scope, "ulog_note", uc_ulog_note);
 | |
|  	uc_function_register(ucrun->scope, "ulog_warn", uc_ulog_warn);
 | |
|  	uc_function_register(ucrun->scope, "ulog_err", uc_ulog_err);
 | |
| +	uc_function_register(ucrun->scope, "ulog_dump", uc_ulog_dump);
 | |
|  
 | |
|  	/* add commandline parameters */
 | |
|  	ARGV = ucv_array_new(&ucrun->vm);
 | |
| -- 
 | |
| 2.25.1
 | |
| 
 | 
