elastic / beats

:tropical_fish: Beats - Lightweight shippers for Elasticsearch & Logstash
https://www.elastic.co/products/beats
Other
12.05k stars 4.89k forks source link

[Metricbeat] Driver Library requirements for ODBC package in golang. #29929

Open kush-elastic opened 2 years ago

kush-elastic commented 2 years ago

Hi We are trying to create IBM DB2 Metricbeat Module. but we are facing issues while building binary.

Here is the detailed technical analysis of go_ibm_db and odbc package.

Following are the steps and issues we are facing for go_ibm_db package: Using go_ibm_db library with the cli driver before building metricbeat

export DB2HOME=/root/ibm/clidriver export CGO_CFLAGS=-I$DB2HOME/include export CGO_LDFLAGS=-L$DB2HOME/lib export LD_LIBRARY_PATH=/root/ibm/clidriver/lib

After setting these env variables manually, we tried building the metricbeat:

Following are the steps and issues we are facing for odbc package: Using odbc library with the cli driver before building metricbeat

After installing unixODBC manually, we tried building the metricbeat:

How should we proceed further?

I am attaching the IBM DB2 issue here. and also SQL Module issue as they have faced somewhat similar issues and were also using the same odbc library.

Related #13106 Related #13257

elasticmachine commented 2 years ago

Pinging @elastic/integrations (Team:Integrations)

elasticmachine commented 2 years ago

Pinging @elastic/security-external-integrations (Team:Security-External Integrations)

mtojek commented 2 years ago

ping @jsoriano @andrewkroh @sayden

I'm wondering if we can work out a convenient solution to this problem. Otherwise, we won't be able to integrate with products requiring dynamic libraries.

ChrsMark commented 2 years ago

This reminds me the issues we had at https://github.com/elastic/beats/pull/8870.

mtojek commented 2 years ago

I'm wondering if we can somehow extend the SQL module with IBM DB support.

jsoriano commented 2 years ago

This reminds me the issues we had at #8870.

Yes, the situation seems to be quite similar.

I have tried to build metricbeat with the go_ibm_db driver, following the instructions given in the project, and as Kush mentions, metricbeat builds. Then to run it you need to pass the same environmental variables, otherwise, metricbeat fails to start:

error while loading shared libraries: libdb2.so.1: cannot open shared object file: No such file or directory

I think that to avoid this problem we would need to fork the library, and change how it is initialized. It is BSD-3, so in principle we could do it, but it'd be a bit inconvenient to need to maintain it long term. But this could be something to evaluate.

With the proper environment variables, then the SQL module seems to work. With a config like the following one I get connectivity errors (expected because I don't have db2 running locally :D):

metricbeat.modules:
  - module: sql
    metricsets: [query]
    hosts: ['HOSTNAME=localhost;DATABASE=db;PORT=1234;UID=username;PWD=password']
    driver: go_ibm_db
    sql_query: 'select ...
Error fetching data for metricset sql.query: error opening connection: testing connection: SQLDriverConnect: {08001} [IBM][CLI Driver] SQL30081N  A communication error has been detected....

So to include it in metricbeat I think we should, at least, do:

Other ideas explored in the document shared by Christos could apply also here.

It could be specially interesting to try again the plugin approach, this is something that could be nice for any other tricky connector, but we would have to think on how to distribute plugins, what opens its own cans of worms.


A possibly more future-proof approach is to try to do it in a separate binary that is started by Elastic Agent. Then it could be implemented using any library that is convenient to integrate with DB2. An integration would be added that uses this binary.

I wouldn't know how to start with this, but possibly a good starting point is to check how to add an spec (as these ones) and what is needed for elastic-agent to discover these binaries on run time.

Pinging also @kvch and @blakerouse in case they have other ideas.

andrewkroh commented 2 years ago

In order to create a dependency on a shared object that is not distributed with Beats (it's an optional dependency) we need to use dlopen to dynamically load it at runtime.

If Beats is linked against the shared object (i.e. it shows up when you do ldd <beatname>) then everyone that uses the Beat must have the library present on their system. That's only reasonable if we provide the shared object (or a stub) with our packages.

The journald input in Filebeat (uses libsystemd) and the system/package dataset in Auditbeat (uses librpm) are examples of this.

botelastic[bot] commented 1 year ago

Hi! We just realized that we haven't looked into this issue in a while. We're sorry!

We're labeling this issue as Stale to make it hit our filters and make sure we get back to it as soon as possible. In the meantime, it'd be extremely helpful if you could take a look at it as well and confirm its relevance. A simple comment with a nice emoji will be enough :+1. Thank you for your contribution!

mattia-eleuteri commented 1 year ago

very relevent in our case 👍

botelastic[bot] commented 3 months ago

Hi! We just realized that we haven't looked into this issue in a while. We're sorry!

We're labeling this issue as Stale to make it hit our filters and make sure we get back to it as soon as possible. In the meantime, it'd be extremely helpful if you could take a look at it as well and confirm its relevance. A simple comment with a nice emoji will be enough :+1. Thank you for your contribution!