Git Product home page Git Product logo

node_bpfcc's Introduction

bpfcc

Node.js frontend (aka bindings) for iovisor's BPF Compiler Collection (BCC).

๐Ÿ’ก Examples ย โ€ขย  ๐Ÿ“š API reference

Usage

Installing

First you need to install BCC on your system. For modern distros (Ubuntu 20.04+) you can use the repository packages. You don't need to install everything, only the C library & development files; for instance, on Ubuntu the following should be enough:

sudo apt install libbpfcc-dev

Then install this module and bpf, which is required as a peer dependency:

npm install bpfcc bpf

Loading & attaching programs

To use it, first pass your program to load or loadSync to compile it:

const { loadSync } = require('bpfcc')

const bpf = loadSync(`
    #include <uapi/linux/ptrace.h>
    #include <linux/blkdev.h>

    BPF_HISTOGRAM(dist);
    BPF_HISTOGRAM(dist_linear);

    int kprobe__blk_account_io_done(struct pt_regs *ctx, struct request *req) {
        dist.increment(bpf_log2l(req->__data_len / 1024));
        dist_linear.increment(req->__data_len / 1024);
        return 0;
    }
`)

Then you need to load & attach your functions to kernel events using the attach* methods:

bpf.attachKprobe('blk_account_io_done', 'kprobe__blk_account_io_done')

Note: By default, functions starting with prefixes like kprobe__ are automatically detected and attached, so the above isn't necessary in this case.

At a later point, if you no longer need it, you can use bpf.detachAll() to detach and unload everything from the kernel. If you don't, it might get called by the GC at some point, but it's not recommended to rely on this.

Accessing maps

Once tracing has started, we can communicate with our eBPF program by accessing its maps (using the get*Map methods). In our case we have two array maps, with uint32 values:

const dist = bpf.getRawArrayMap('dist')
const distLinear = bpf.getRawArrayMap('dist_linear')

// Retrieve current values & parse them
const ys = [...dist].map(x => x.readUInt32LE(0))
console.log(ys)

getRaw*Map methods provide a raw interface which returns Buffers, so we had to parse the values ourselves. But there are also high-level versions that take a conversion object. For convenience, bpf provides a conversion for uint32, so we can write:

const { u32type } = require('bpf')

const dist = bpf.getArrayMap('dist', u32type)
const distLinear = bpf.getArrayMap('dist_linear', u32type)

console.log( [...dist] )

Refer to the bpf module for details on the interface.

The full source code of this example is in bitehist.ts. Remember you'll probably need root to run.

Troubleshooting

Remember that not all features may be available in the kernel you are running, even if they're present in the API and typings. Trying to use a non-available feature will generally result in an EINVAL error.

A reference of eBPF features and minimum kernel versions required for them can be found here.

node_bpfcc's People

Contributors

mildsunrise avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

dio

node_bpfcc's Issues

Failed to run example file.

Hi,

I tried the example files on Ubuntu 20.04 and failed, would you please help to check the root cause?

The output is below.

bizconf@bizconf:~/work/bpf-node$ tsc test.ts --downlevelIteration
bizconf@bizconf:~/work/bpf-node$ node test.js 
Loading program...
bpf: Failed to load program: Operation not permitted

/home/bizconf/work/bpf-node/node_modules/bpfcc/dist/exception.js:26
    throw new BCCError(status.code, status.msg);
    ^

BCCError: Failed to load kprobe__blk_account_io_done: -1
    at Object.checkStatus (/home/bizconf/work/bpf-node/node_modules/bpfcc/dist/exception.js:26:11)
    at BPFModule.attachKprobe (/home/bizconf/work/bpf-node/node_modules/bpfcc/dist/index.js:87:28)
    at Object.kprobe (/home/bizconf/work/bpf-node/node_modules/bpfcc/dist/index.js:304:36)
    at BPFModule.autoload (/home/bizconf/work/bpf-node/node_modules/bpfcc/dist/index.js:309:33)
    at post (/home/bizconf/work/bpf-node/node_modules/bpfcc/dist/index.js:35:17)
    at genericLoad (/home/bizconf/work/bpf-node/node_modules/bpfcc/dist/index.js:31:19)
    at Object.loadSync (/home/bizconf/work/bpf-node/node_modules/bpfcc/dist/index.js:50:12)
    at Object.<anonymous> (/home/bizconf/work/bpf-node/test.js:27:19)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10) {
  code: -1
}

The test.ts file is here, I just copy it from bitehist.ts of example directory.

import { loadSync } from 'bpfcc'
import { u32type } from 'bpf'

// Upload BPF to kernel
console.log('Loading program...')
const bpf = loadSync(`
    #include <uapi/linux/ptrace.h>
    #include <linux/blkdev.h>
    BPF_HISTOGRAM(dist);
    BPF_HISTOGRAM(dist_linear);
    int kprobe__blk_account_io_done(struct pt_regs *ctx, struct request *req) {
        dist.increment(bpf_log2l(req->__data_len / 1024));
        dist_linear.increment(req->__data_len / 1024);
        return 0;
    }
`)

console.log('Done! Tracing...')
const dist = bpf.getArrayMap('dist', u32type)
setInterval(() => {
    const ys = [...dist]
    const maxY = Math.max(...ys)
    const cols = 68
    const rpad = (x: string, n: number) => ' '.repeat(Math.max(n - x.length, 0)) + x.substr(0, n)
    console.log('\nDistribution:\n' + ys.map((y, i) =>
        rpad(`${y}`, 8) + ' |' + '#'.repeat(Math.round(y / maxY * cols))
    ).join('\n'))
}, 2000)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.