Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Option to easily discard bytes explicitely without label #369

Closed
aibor opened this issue Apr 2, 2024 · 5 comments · Fixed by #376
Closed

Option to easily discard bytes explicitely without label #369

aibor opened this issue Apr 2, 2024 · 5 comments · Fixed by #376

Comments

@aibor
Copy link
Contributor

aibor commented Apr 2, 2024

As described in the documentation, padding bytes in the counter key struct need to be considered when decoding the values.
The documentation suggests just to include the padding space in the previous value.

In case the structure is not as simple, it can get tricky and I need to define "reserved" fields. Those end up as label unnecessarily.

So, in order to avoid that, with a "discard" decoder I could explicitely discard such padding bytes.

I'd be happy to provide a patch, if you like the idea. Regarding the naming of such a decoder I'm open to suggestions.

Edit: It seems better to just add a simple "discard" or "skip" config flag to the label.

@aibor aibor changed the title New discard decoder for explicitely discarding padding bytes Option to easily discard bytes Apr 2, 2024
@aibor aibor changed the title Option to easily discard bytes Option to easily discard bytes explicitely without label Apr 2, 2024
@bobrik
Copy link
Contributor

bobrik commented Apr 2, 2024

Do you have an example struct that requires this? If we want to have this functionality, it needs an example attached.

@aibor
Copy link
Contributor Author

aibor commented Apr 3, 2024

Right now I have a struct like this:

struct inet_frags_counter_key_t {
  u32 ifindex;
  u8 ip_version;
  u8 ip_protocol;
};

Due to alignment, it is 8 byte long. In the config, I can't use size: 3 for the label ip_protocol, because it is an invalid length. So I need to use a config like this:

metrics:
  counters:
    - name: frags_total
      help: number of fragments seen
      labels: 
        - name: interface
          size: 4
          decoders:
            - name: ifname
        - name: ip_version
          size: 1
          decoders:
            - name: uint
        - name: ip_protocol
          size: 1
          decoders:
            - name: uint
        - name: padding_bytes
          size: 2
          decoders:
            - name: uint

The label "padding_bytes" is added just to get the proper map key size.

In order to avoid the unnecessary label, an additional config key (e.g. discard: true) might be a straight forward solution?
So, the config would look like this:

metrics:
  counters:
    - name: frags_total
      help: number of fragments seen
      labels:
        - name: interface
          size: 4
          decoders:
            - name: ifname
        - name: ip_version
          size: 1
          decoders:
            - name: uint
        - name: ip_protocol
          size: 1
          decoders:
            - name: uint
        - size: 2
          discard: true

@bobrik
Copy link
Contributor

bobrik commented Apr 3, 2024

I see. Normally I just upsize the struct members (u8 -> u16), which doesn't change the struct size.

#include <stdint.h>

struct inet_frags_counter_key_u8_t {
  uint32_t ifindex;
  uint8_t ip_version;
  uint8_t ip_protocol;
};

struct inet_frags_counter_key_u16_t {
  uint32_t ifindex;
  uint16_t ip_version;
  uint16_t ip_protocol;
};

struct inet_frags_counter_key_u8_t	key_u8	= {};
struct inet_frags_counter_key_u16_t	key_u16 = {};
$ gcc -c -g hole.c
$ pahole --structs hole.o
struct inet_frags_counter_key_u8_t {
	uint32_t                   ifindex;              /*     0     4 */
	uint8_t                    ip_version;           /*     4     1 */
	uint8_t                    ip_protocol;          /*     5     1 */

	/* size: 8, cachelines: 1, members: 3 */
	/* padding: 2 */
	/* last cacheline: 8 bytes */
};
struct inet_frags_counter_key_u16_t {
	uint32_t                   ifindex;              /*     0     4 */
	uint16_t                   ip_version;           /*     4     2 */
	uint16_t                   ip_protocol;          /*     6     2 */

	/* size: 8, cachelines: 1, members: 3 */
	/* last cacheline: 8 bytes */
};

I can see an argument to add discard: true at the end or padding: 2 to ip_protocol, but I'm also a bit worried about enabling two mechanisms to do the same thing. What do you think?

@aibor
Copy link
Contributor Author

aibor commented Apr 3, 2024

Using longer types definitely is a simple workaround and would works for my use cases as well.

But if it were implemented, I'd prefer your padding key solution. This makes configuration even easier and should work for all relevant cases I can think of (padding at the end or in between, multiple fields with padding).

@bobrik
Copy link
Contributor

bobrik commented Apr 3, 2024

I'm open to a PR to add padding support.

aibor added a commit to aibor/ebpf_exporter that referenced this issue Apr 4, 2024
Padding bytes in the map key struct need to be considered in the config
of the label. This is done by choosing a larger size for the label's value.
For most cases this works fine.

This commit adds a new config key for labels that allows to specify padding
bytes explicitly so they can be skipped by decoders.

Closes cloudflare#369
aibor added a commit to aibor/ebpf_exporter that referenced this issue Apr 7, 2024
Padding bytes in the map key struct need to be considered in the config
of the label. This is done by choosing a larger size for the label's value.
For most cases this works fine.

This commit adds a new config key for labels that allows to specify padding
bytes explicitly so they can be skipped by decoders.

Closes cloudflare#369
aibor added a commit to aibor/ebpf_exporter that referenced this issue Apr 7, 2024
Padding bytes in the map key struct need to be considered in the config
of the label. This is done by choosing a larger size for the label's value.
For most cases this works fine.

This commit adds a new config key for labels that allows to specify padding
bytes explicitly so they can be skipped by decoders.

Closes cloudflare#369
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants