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

Feature/32089 generic sql enchancement #32293

Merged
Merged
Show file tree
Hide file tree
Changes from 41 commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
4c62bba
x-pack/filebeat/module/cisco: remove invalid values from ECS fields (…
agithomas May 16, 2022
3c39232
Merge branch 'elastic:main' into main
agithomas May 19, 2022
d1c97af
Merge branch 'elastic:main' into main
agithomas May 27, 2022
aa4f464
Merge branch 'elastic:main' into main
agithomas May 31, 2022
d9e070c
Merge branch 'elastic:main' into main
agithomas Jun 3, 2022
a089576
Merge branch 'elastic:main' into main
agithomas Jun 5, 2022
5173fda
Merge branch 'elastic:main' into main
agithomas Jun 6, 2022
f429eaf
Merge branch 'elastic:main' into main
agithomas Jul 1, 2022
4640072
Merge branch 'elastic:main' into main
agithomas Jul 6, 2022
c795711
Merge branch 'elastic:main' into main
agithomas Jul 7, 2022
ea7b9cf
Merge branch 'elastic:main' into main
agithomas Jul 11, 2022
978a3fe
Upgrade Generic SQL to support new connection string and special char…
agithomas Jul 11, 2022
395d974
Code formatted
agithomas Jul 11, 2022
9ee53a5
Changes to support Oracle for integration testing
agithomas Jul 11, 2022
746a767
Merge branch 'elastic:main' into main
agithomas Jul 12, 2022
6d1fe61
Merge remote-tracking branch 'upstream/main' into feature/32089-gener…
agithomas Jul 12, 2022
702ee4c
Improved the change log entry
agithomas Jul 12, 2022
901a010
Modified the documentation
agithomas Jul 19, 2022
e2fcedc
Revert "Modified the documentation"
agithomas Jul 19, 2022
053ca1d
Improved the change log entry
agithomas Jul 19, 2022
50bfaee
Added oracle connectiions pre-requesites
agithomas Jul 20, 2022
aba3c57
Improved the documentation
agithomas Jul 20, 2022
f75a9ab
Merge branch 'elastic:main' into main
agithomas Jul 20, 2022
2b1e322
Merge branch 'feature/32089-generic-sql-enchancement' of github.com:a…
agithomas Jul 20, 2022
bcd5153
Fixed the documentation issue
agithomas Jul 20, 2022
3a8d405
Documention rollback to solve cicd issues
agithomas Jul 20, 2022
bcddf95
Documentation rollback
agithomas Jul 20, 2022
c848643
Revert "Improved the change log entry"
agithomas Jul 20, 2022
e424e9b
Added oracle documentation
agithomas Jul 20, 2022
27bacae
Oracle documentation updated
agithomas Jul 20, 2022
7723142
Merge branch 'elastic:main' into main
agithomas Sep 23, 2022
1bad1ac
Merge branch 'elastic:main' into main
agithomas Oct 20, 2022
be6298a
Merge branch 'elastic:main' into main
agithomas Oct 21, 2022
047a198
Merge branch 'elastic:main' into main
agithomas Nov 3, 2022
7a5c22b
Changes made as per review comments
agithomas Nov 10, 2022
1007f68
Minor documentation corrections
agithomas Nov 10, 2022
85a89d8
Merge branch 'elastic:main' into main
agithomas Nov 10, 2022
fcc225d
Minor corrections to changelog
agithomas Nov 10, 2022
5de710b
Resolving conflicts
agithomas Nov 10, 2022
6b08991
Merge branch 'main' into feature/32089-generic-sql-enchancement
agithomas Nov 10, 2022
877ca6f
Resolved typo
agithomas Nov 10, 2022
451dd8f
Merge branch 'feature/32089-generic-sql-enchancement' of https://gith…
agithomas Nov 10, 2022
3da67a8
Rearranged doc section
agithomas Nov 10, 2022
a1ec6ab
Rolling back changes
agithomas Nov 10, 2022
33c7da4
Document updated
agithomas Nov 10, 2022
8c4908d
Updated ORACLE_SID reference from doc
agithomas Nov 10, 2022
84dfa27
Changes as per review comments addded
agithomas Nov 14, 2022
b32336e
Changes as per review comments addded
agithomas Nov 14, 2022
c0ee4ac
Merge branch 'main' of https://github.com/agithomas/beats into featur…
agithomas Nov 14, 2022
0e05f65
Merge branch 'main' of https://github.com/elastic/beats into feature/…
agithomas Nov 14, 2022
79acb88
Update changelog
agithomas Nov 14, 2022
f26385b
Change log corrected
agithomas Nov 14, 2022
f5ce180
Update metricbeat/docs/modules/sql.asciidoc
agithomas Nov 15, 2022
a011101
Update metricbeat/docs/modules/sql.asciidoc
agithomas Nov 15, 2022
22d2848
Update metricbeat/docs/modules/sql.asciidoc
agithomas Nov 15, 2022
a8a8b7f
Update metricbeat/docs/modules/sql.asciidoc
agithomas Nov 15, 2022
f7d2c99
Updated sql.asciidoc
agithomas Nov 15, 2022
c575d05
Merge branch 'main' into feature/32089-generic-sql-enchancement
agithomas Nov 15, 2022
190a8dc
Updated the sql.asciidoc
agithomas Nov 15, 2022
c15232e
Merge branch 'feature/32089-generic-sql-enchancement' of https://gith…
agithomas Nov 15, 2022
d8d20f6
Updated the sql.asciidoc
agithomas Nov 15, 2022
9d36cc1
Updated generated doc
agithomas Nov 15, 2022
5a2c984
Merge branch 'main' into feature/32089-generic-sql-enchancement
agithomas Nov 15, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.next.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ https://github.com/elastic/beats/compare/v8.2.0\...main[Check the HEAD diff]
- Fix logstash cgroup mappings {pull}33131[33131]
- Remove unused `elasticsearch.node_stats.indices.bulk.avg_time.bytes` mapping {pull}33263[33263]
- Add tags to events based on parsed identifier. {pull}33472[33472]
- Upgrade Generic SQL module to support new connection string and special character support for Oracle Database. {issue}32089[32089]

*Packetbeat*

Expand Down
51 changes: 50 additions & 1 deletion metricbeat/docs/modules/sql.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ each row.

`sql_query`:: The single query you want to run. (`Backward Compatibility`). Also provide corresponding `sql_response_format`: either `variables` or `table`


[float]
=== Example: capture Innodb-related metrics

Expand Down Expand Up @@ -228,7 +229,7 @@ for each row. For example, this event is created for the first row:
----

[float]
=== Example: get the buffer catch hit ratio in Oracle
==== Example: get the buffer catch hit ratio in Oracle
agithomas marked this conversation as resolved.
Show resolved Hide resolved

This `sql.yml` configuration shows how to get the buffer cache hit ratio:

Expand Down Expand Up @@ -298,6 +299,8 @@ The example generates this event:
"ephemeral_id": "49e00060-0fa4-4b34-80f1-446881f7a788"
}
}


----

[float]
Expand Down Expand Up @@ -551,6 +554,52 @@ This creates a combined event as below, where `blks_hit`, `blks_read`, `checkpoi
}
----

== Host Setup (Oracle)
agithomas marked this conversation as resolved.
Show resolved Hide resolved

==== Oracle Database Connection Pre-requisites

To get connected with the Oracle Database ORACLE_SID, ORACLE_BASE, ORACLE_HOME environment variables should be set.
agithomas marked this conversation as resolved.
Show resolved Hide resolved

For example: Let’s consider Oracle Database 21c installation using RPM manually by following https://docs.oracle.com/en/database/oracle/oracle-database/21/ladbi/running-rpm-packages-to-install-oracle-database.html[this] link, environment variables should be set as follows:

`ORACLE_BASE=/opt/oracle/oradata`
`ORACLE_HOME=/opt/oracle/product/21c/dbhome_1`
agithomas marked this conversation as resolved.
Show resolved Hide resolved
Also, add `ORACLE_HOME/bin` to the `PATH` environment variable.

===== Oracle Instant Client Installation

Oracle Instant Client enables development and deployment of applications that connect to Oracle Database. The Instant Client libraries provide the necessary network connectivity and advanced data features to make full use of Oracle Database. If you have OCI Oracle server which comes with these libraries pre-installed, you don't need a separate client installation.

The OCI library install few Client Shared Libraries that must be referenced on the machine where Metricbeat is installed. Please follow https://docs.oracle.com/en/database/oracle/oracle-database/21/lacli/install-instant-client-using-zip.html#GUID-D3DCB4FB-D3CA-4C25-BE48-3A1FB5A22E84[this] link for OCI Instant Client set up. The OCI Instant Client is available with the Oracle Universal Installer, RPM file or ZIP file. Download links can be found https://www.oracle.com/database/technologies/instant-client/downloads.html[here].

===== Enable Oracle Listener

The Oracle listener is a service that runs on the database host and receives requests from Oracle clients. Make sure that https://docs.oracle.com/cd/B19306_01/network.102/b14213/lsnrctl.htm[listener] should be running.
To check if the listener is running or not, run:

`lsnrctl STATUS`
agithomas marked this conversation as resolved.
Show resolved Hide resolved

If the listener is not running, use the command to start:

`lsnrctl START`
agithomas marked this conversation as resolved.
Show resolved Hide resolved

Then, Metricbeat can be launched.

==== Host Configuration for Oracle

The following two types of host configurations are supported:

1. Old style host configuration for backwards compatibility:
agithomas marked this conversation as resolved.
Show resolved Hide resolved
a. `hosts: ["user/[email protected]:1521/ORCLPDB1.localdomain"]`
b. `hosts: ["user/[email protected]:1521/ORCLPDB1.localdomain as sysdba"]`

2. DSN host configuration:
a. `hosts: ['user="user" password="pass" connectString="0.0.0.0:1521/ORCLPDB1.localdomain"']`
b. `hosts: ['user="user" password="password" connectString="host:port/service_name" sysdba=true']`

Note: If the password contains the backslash (`\`) character, it must be escaped with a backslash. For example, if the password is `my\_password`, it should be written as `my\\_password`.
agithomas marked this conversation as resolved.
Show resolved Hide resolved


:edit_url:

[float]
Expand Down
52 changes: 50 additions & 2 deletions x-pack/metricbeat/module/sql/_meta/docs.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ each row.

`sql_query`:: The single query you want to run. (`Backward Compatibility`). Also provide corresponding `sql_response_format`: either `variables` or `table`


[float]
=== Example: capture Innodb-related metrics

Expand Down Expand Up @@ -214,7 +215,7 @@ for each row. For example, this event is created for the first row:
----

[float]
=== Example: get the buffer catch hit ratio in Oracle
==== Example: get the buffer catch hit ratio in Oracle

This `sql.yml` configuration shows how to get the buffer cache hit ratio:

Expand Down Expand Up @@ -284,6 +285,8 @@ The example generates this event:
"ephemeral_id": "49e00060-0fa4-4b34-80f1-446881f7a788"
}
}


----

[float]
Expand Down Expand Up @@ -535,4 +538,49 @@ This creates a combined event as below, where `blks_hit`, `blks_read`, `checkpoi
"dataset": "sql.query"
}
}
----
----

== Host Setup (Oracle)

==== Oracle Database Connection Pre-requisites

To get connected with the Oracle Database ORACLE_SID, ORACLE_BASE, ORACLE_HOME environment variables should be set.

For example: Let’s consider Oracle Database 21c installation using RPM manually by following https://docs.oracle.com/en/database/oracle/oracle-database/21/ladbi/running-rpm-packages-to-install-oracle-database.html[this] link, environment variables should be set as follows:

`ORACLE_BASE=/opt/oracle/oradata`
`ORACLE_HOME=/opt/oracle/product/21c/dbhome_1`
Also, add `ORACLE_HOME/bin` to the `PATH` environment variable.

===== Oracle Instant Client Installation

Oracle Instant Client enables development and deployment of applications that connect to Oracle Database. The Instant Client libraries provide the necessary network connectivity and advanced data features to make full use of Oracle Database. If you have OCI Oracle server which comes with these libraries pre-installed, you don't need a separate client installation.

The OCI library install few Client Shared Libraries that must be referenced on the machine where Metricbeat is installed. Please follow https://docs.oracle.com/en/database/oracle/oracle-database/21/lacli/install-instant-client-using-zip.html#GUID-D3DCB4FB-D3CA-4C25-BE48-3A1FB5A22E84[this] link for OCI Instant Client set up. The OCI Instant Client is available with the Oracle Universal Installer, RPM file or ZIP file. Download links can be found https://www.oracle.com/database/technologies/instant-client/downloads.html[here].

===== Enable Oracle Listener

The Oracle listener is a service that runs on the database host and receives requests from Oracle clients. Make sure that https://docs.oracle.com/cd/B19306_01/network.102/b14213/lsnrctl.htm[listener] should be running.
To check if the listener is running or not, run:

`lsnrctl STATUS`

If the listener is not running, use the command to start:

`lsnrctl START`

Then, Metricbeat can be launched.

==== Host Configuration for Oracle

The following two types of host configurations are supported:

1. Old style host configuration for backwards compatibility:
a. `hosts: ["user/[email protected]:1521/ORCLPDB1.localdomain"]`
b. `hosts: ["user/[email protected]:1521/ORCLPDB1.localdomain as sysdba"]`

2. DSN host configuration:
a. `hosts: ['user="user" password="pass" connectString="0.0.0.0:1521/ORCLPDB1.localdomain"']`
b. `hosts: ['user="user" password="password" connectString="host:port/service_name" sysdba=true']`

Note: If the password contains the backslash (`\`) character, it must be escaped with a backslash. For example, if the password is `my\_password`, it should be written as `my\\_password`.
5 changes: 5 additions & 0 deletions x-pack/metricbeat/module/sql/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,8 @@ services:
extends:
file: ../../../../metricbeat/module/postgresql/docker-compose.yml
service: postgresql

oracle:
extends:
file: ../../../../x-pack/metricbeat/module/oracle/docker-compose.yml
service: oracle
37 changes: 35 additions & 2 deletions x-pack/metricbeat/module/sql/query/dsn.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,52 @@
package query

import (
"fmt"
"net/url"

"github.com/go-sql-driver/mysql"
"github.com/godror/godror"
"github.com/godror/godror/dsn"

"github.com/elastic/beats/v7/metricbeat/mb"
)

// ConnectionDetails contains all possible data that can be used to create a connection with
// an Oracle db
type ConnectionDetails struct {
Username string `config:"username"`
Password string `config:"password"`
Driver string `config:"driver"`
}

// ParseDSN tries to parse the host
func ParseDSN(mod mb.Module, host string) (mb.HostData, error) {
// TODO: Add support for `username` and `password` as module options

config := ConnectionDetails{}
if err := mod.UnpackConfig(&config); err != nil {
return mb.HostData{}, fmt.Errorf("error parsing config file: %w", err)
}
if config.Driver == "oracle" {
params, err := godror.ParseDSN(host)
if err != nil {
return mb.HostData{}, fmt.Errorf("error trying to parse connection string in field 'hosts': %w", err)
}
if params.Username == "" {
params.Username = config.Username
}
if params.Password.Secret() == "" {
params.StandaloneConnection = true
params.Password = dsn.NewPassword(config.Password)
}
return mb.HostData{
URI: params.StringWithPassword(),
SanitizedURI: params.ConnectString,
agithomas marked this conversation as resolved.
Show resolved Hide resolved
Host: params.String(),
User: params.Username,
Password: params.Password.Secret(),
}, nil
}
agithomas marked this conversation as resolved.
Show resolved Hide resolved
sanitized := sanitize(host)

return mb.HostData{
URI: host,
SanitizedURI: sanitized,
Expand Down
77 changes: 73 additions & 4 deletions x-pack/metricbeat/module/sql/query/query_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ package query
import (
"fmt"
"net"
"os"
"testing"
"time"

"github.com/godror/godror"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

Expand Down Expand Up @@ -40,15 +43,13 @@ func TestMySQL(t *testing.T) {
Driver: "mysql",
Query: "select table_schema, table_name, engine, table_rows from information_schema.tables where table_rows > 0;",
ResponseFormat: tableResponseFormat,

RawData: rawData{
Enabled: true,
},
},
Host: mysql.GetMySQLEnvDSN(service.Host()),
Assertion: assertFieldNotContains("service.address", ":test@"),
}

t.Run("fetch", func(t *testing.T) {
testFetch(t, cfg)
})
Expand Down Expand Up @@ -226,6 +227,26 @@ func TestPostgreSQL(t *testing.T) {
})
}

func TestOracle(t *testing.T) {
service := compose.EnsureUp(t, "oracle")
host, port, _ := net.SplitHostPort(service.Host())
cfg := testFetchConfig{
config: config{
Driver: "oracle",
Query: `SELECT name, physical_reads, db_block_gets, consistent_gets, 1 - (physical_reads / (db_block_gets + consistent_gets)) "Hit_Ratio" FROM V$BUFFER_POOL_STATISTICS`,
ResponseFormat: tableResponseFormat,
RawData: rawData{
Enabled: true,
},
},
Host: GetOracleConnectionDetails(t, host, port),
Assertion: assertFieldContainsFloat64("Hit_Ratio", 0.0),
}
t.Run("fetch", func(t *testing.T) {
testFetch(t, cfg)
})
}

func testFetch(t *testing.T, cfg testFetchConfig) {
m := mbtest.NewFetcher(t, getConfig(cfg))
events, errs := m.FetchEvents()
Expand Down Expand Up @@ -256,11 +277,9 @@ func getConfig(cfg testFetchConfig) map[string]interface{} {
"raw_data.enabled": cfg.config.RawData.Enabled,
"merge_results": cfg.config.MergeResults,
}

if cfg.config.ResponseFormat != "" {
values["sql_response_format"] = cfg.config.ResponseFormat
}

return values
}

Expand All @@ -272,3 +291,53 @@ func assertFieldNotContains(field, s string) func(t *testing.T, event beat.Event
require.NotContains(t, value.(string), s)
}
}

func assertFieldContainsFloat64(field string, limit float64) func(t *testing.T, event beat.Event) {
return func(t *testing.T, event beat.Event) {
value, err := event.GetValue("sql.metrics.hit_ratio")
assert.NoError(t, err)
require.GreaterOrEqual(t, value.(float64), limit)
}
}

func GetOracleConnectionDetails(t *testing.T, host string, port string) string {
params, err := godror.ParseDSN(GetOracleConnectString(host, port))
require.Empty(t, err)
return params.StringWithPassword()
}

// GetOracleEnvServiceName returns the service name to use with Oracle testing server or the value of the environment variable ORACLE_SERVICE_NAME if not empty
func GetOracleEnvServiceName() string {
serviceName := os.Getenv("ORACLE_SERVICE_NAME")
if len(serviceName) == 0 {
serviceName = "ORCLCDB.localdomain"
}
return serviceName
}

// GetOracleEnvUsername returns the username to use with Oracle testing server or the value of the environment variable ORACLE_USERNAME if not empty
func GetOracleEnvUsername() string {
username := os.Getenv("ORACLE_USERNAME")
if len(username) == 0 {
username = "sys"
}
return username
}

// GetOracleEnvUsername returns the port of the Oracle server or the value of the environment variable ORACLE_PASSWORD if not empty
func GetOracleEnvPassword() string {
password := os.Getenv("ORACLE_PASSWORD")
if len(password) == 0 {
password = "Oradoc_db1" // #nosec
}
return password
}

func GetOracleConnectString(host string, port string) string {
time.Sleep(300 * time.Second)
connectString := os.Getenv("ORACLE_CONNECT_STRING")
if len(connectString) == 0 {
connectString = fmt.Sprintf("%s/%s@%s:%s/%s as sysdba", GetOracleEnvUsername(), GetOracleEnvPassword(), host, port, GetOracleEnvServiceName())
}
return connectString
}
Loading