linux-trace-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* how to register an event handler for the instance
@ 2022-05-06 16:18 christopher lee
  2022-05-07  5:02 ` Tzvetomir Stoyanov
  0 siblings, 1 reply; 6+ messages in thread
From: christopher lee @ 2022-05-06 16:18 UTC (permalink / raw)
  To: linux-trace-devel, rostedt, tz.stoyanov

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?

https://trace-cmd.org/Documentation/libtraceevent/libtraceevent-reg_event_handler.html

thanks for any information.

Best regards,
Chrit

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: how to register an event handler for the instance
  2022-05-06 16:18 how to register an event handler for the instance christopher lee
@ 2022-05-07  5:02 ` Tzvetomir Stoyanov
  2022-05-11 18:33   ` christopher lee
  0 siblings, 1 reply; 6+ messages in thread
From: Tzvetomir Stoyanov @ 2022-05-07  5:02 UTC (permalink / raw)
  To: christopher lee; +Cc: Linux Trace Devel, Steven Rostedt

On Fri, May 6, 2022 at 7:18 PM christopher lee
<christopher.lee.eu@gmail.com> 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/

> https://trace-cmd.org/Documentation/libtraceevent/libtraceevent-reg_event_handler.html
>
> thanks for any information.
>
> Best regards,
> Chrit



-- 
Tzvetomir (Ceco) Stoyanov
VMware Open Source Technology Center

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: how to register an event handler for the instance
  2022-05-07  5:02 ` Tzvetomir Stoyanov
@ 2022-05-11 18:33   ` christopher lee
  2022-05-12  3:05     ` Tzvetomir Stoyanov
  2022-05-16 18:14     ` Steven Rostedt
  0 siblings, 2 replies; 6+ messages in thread
From: christopher lee @ 2022-05-11 18:33 UTC (permalink / raw)
  To: Tzvetomir Stoyanov; +Cc: Linux Trace Devel, Steven Rostedt

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@gmail.com> 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
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?
 

        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);                          
                free(raw_buf);                                        
                free(cpu);                                            
        } 

Best regards,
Christ

> 

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: how to register an event handler for the instance
  2022-05-11 18:33   ` christopher lee
@ 2022-05-12  3:05     ` Tzvetomir Stoyanov
  2022-05-16 18:14     ` Steven Rostedt
  1 sibling, 0 replies; 6+ messages in thread
From: Tzvetomir Stoyanov @ 2022-05-12  3:05 UTC (permalink / raw)
  To: christopher lee; +Cc: Linux Trace Devel, Steven Rostedt

On Wed, May 11, 2022 at 9:33 PM christopher lee
<christopher.lee.eu@gmail.com> 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@gmail.com> 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
> 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?

Hi Christ,
All recorded events are in trace_pipe_raw file, so yes - if you want
to parse the trace event info, the first step is to read the events.
It consumes lots of CPU resources because there are a lot of events to
read and parse. I would suggest using the tracefs_iterate_raw_events()
API to read the events, as it is optimized to read the trace_pipe_raw
file in an efficient way, or at least to look at its implementation if
you do not want to use the tracefs library.

static int read_callback(struct tep_event *event, struct tep_record
*record, int cpu, void *context)
{
     ...
     tep_print_event();
     ...
}

tracefs_iterate_raw_events(tep, instance, NULL, 0, read_callback, ...);

>
>
>         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);
>                 free(raw_buf);
>                 free(cpu);
>         }
>
> Best regards,
> Christ
>
> >



-- 
Tzvetomir (Ceco) Stoyanov
VMware Open Source Technology Center

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: how to register an event handler for the instance
  2022-05-11 18:33   ` christopher lee
  2022-05-12  3:05     ` Tzvetomir Stoyanov
@ 2022-05-16 18:14     ` Steven Rostedt
  2022-05-16 21:24       ` christopher lee
  1 sibling, 1 reply; 6+ messages in thread
From: Steven Rostedt @ 2022-05-16 18:14 UTC (permalink / raw)
  To: christopher lee; +Cc: Tzvetomir Stoyanov, Linux Trace Devel

On Wed, 11 May 2022 20:33:48 +0200
christopher lee <christopher.lee.eu@gmail.com> 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@gmail.com> 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
> 
> >   


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: how to register an event handler for the instance
  2022-05-16 18:14     ` Steven Rostedt
@ 2022-05-16 21:24       ` christopher lee
  0 siblings, 0 replies; 6+ messages in thread
From: christopher lee @ 2022-05-16 21:24 UTC (permalink / raw)
  To: Steven Rostedt; +Cc: Tzvetomir Stoyanov, Linux Trace Devel

Hi Steven, 

>On Mon, 2022-05-16 at 14:14 -0400, Steven Rostedt wrote:
> 
> 
> Are you only looking to reading some events or all of them?

I created several instances and only enabled one trace event in each
instance. I need to read all trace data from each trace_pipe in each
instance and parse the trace information in each instance's associated
thread. I found that if I read tace_pipe, then parse string, it will
not consume so much CPU resource.

> 
> > 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.
> 

Thanks so much for your support!!

> >  
> > 
> >         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?
> 

no, it is your code, from your example.


> 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);
> 

Got it now, I should measure its CPU usage and get back to you here.

Kind regards,
Christ.
> > 


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-05-16 21:24 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-06 16:18 how to register an event handler for the instance christopher lee
2022-05-07  5:02 ` Tzvetomir Stoyanov
2022-05-11 18:33   ` christopher lee
2022-05-12  3:05     ` Tzvetomir Stoyanov
2022-05-16 18:14     ` Steven Rostedt
2022-05-16 21:24       ` christopher lee

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).