Re: how to register an event handler for the instance

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 11 May 2022 20:33:48 +0200
christopher lee <christopher.lee.eu@xxxxxxxxx> wrote:

> On Sat, 2022-05-07 at 08:02 +0300, Tzvetomir Stoyanov wrote:
> > On Fri, May 6, 2022 at 7:18 PM christopher lee
> > <christopher.lee.eu@xxxxxxxxx> wrote:  
> > > 
> > > Hi all,
> > > 
> > > I use libtraceevent in my trace tool to parse the event log. Now I
> > > allocated an instance, but no idea how to use
> > > tep_register_event_handler() to register a handler for the
> > > instance. Is
> > > it possilbe to register handler for the event in the instance?
> > >   
> > 
> > Hi Chrit,
> > All trace events are the same across all trace instances, thus the
> > handler registered with tep_register_event_handler() handles events
> > from all instances with a given id. That's why there are no
> > "instance"
> > oriented APIs in that library. I would suggest looking at the tracefs
> > library, which is instance aware. It can be used to allocate trace
> > instances and read events from a given instance.
> > 
> > https://trace-cmd.org/Documentation/libtracefs/
> >   
> 
> 
> Hi Tzvetomir Stoyanov,
> 
> Thanks,  instance event handlers work now, but I'm confused with these
> codes, do I have to read trace_pipe_raw? I found that if I didn't read

Are you only looking to reading some events or all of them?

> this file, the handler would not be able to get trace information.
> Becuase if I read this file, and also call tep_print_event() will
> consume lots of CPU resoruce. how can I parse the trace event info
> without reading this file?

The tep_print_event() is easier to use, but you can do things manually as
well. I'll need to write a tutorial to explain this more, but I can help
you here.

>  
> 
>         for (i = 0; ; i++) {                                          
>                 char *raw_buf;                                        
>                 char *cpu;                                            
>                                                                                                     
>                 ret = asprintf(&cpu, "%s/cpu%d", per_cpu, i);         
>                 if (ret < 0)                                          
>                         pdie("Could not allocate memory for cpu buffer
> %d name", i);                
>                                                                                                     
>                 ret = stat(cpu, &st);                                 
>                 if (ret < 0 || !S_ISDIR(st.st_mode)) {                
>                         free(cpu);                                    
>                         goto start;                                   
>                 }                                                     
>                                                                                                     
>                 ret = asprintf(&raw_buf, "%s/trace_pipe_raw", cpu);   
>                 if (ret < 0)                                          
>                         pdie("Could not allocate memory for cpu %d raw
> buffer name", i);            
>                                                                                                     
>                 read_raw_buffer(i, raw_buf);                          

This your own code?

There is a way to read it yourself and to pick and choose the evens you
want.

If you read the raw data, you'll need to read it in page size (found in the
header tep file) tep_get_page_size(). And read one page at a time. Then you
can use the kbuffer code (although I haven't finished the man pages for
them)

Look at the traceevent/kbuffer.h file supplied by libtraceevent.

You can do something like the following:

	unsigned long long ts; // time stamp of event
	struct tep_record record; // should probably be allocated

	/* For little endian 64 bit machines */
	kbuf = kbuffer_alloc(KBUFFER_LSIZE_8, KBUFFER_ENDIAN_LITTLE);

	read(fd, buf, page_size);

	kbuffer_load_subbuffer(kbuf, buf);

	data = kbuffer_read_event(kbuf, &ts);

	if (!data)
		return; // end of sub buffer.

	/* Move the kbuf cursor to the next event */
	kbuffer_next_event(kbuf, NULL);

	/* Now data has the record */

	record.ts = ts;
	record.size = kbuffer_event_size(kbuf);
	record.cpu = cpu; // CPU of the trace_pipe_raw file
	record.data = data;
	record.missed_events = kbuffer_missed_events(kbuf);

	/* Now you can use this record with the other libtraceevent logic */
	
-- Steve


>                 free(raw_buf);                                        
>                 free(cpu);                                            
>         } 
> 
> Best regards,
> Christ
> 
> >   




[Index of Archives]     [Linux USB Development]     [Linux USB Development]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux