fluent-plugin-oceanbase-logs 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3a3230feaa77c86a454f2733f9097f05a2e57f43dd418c1fed7af21d5345a875
4
- data.tar.gz: d2a7f628ddb81778b10c6b9a14ffc1d6fa1fe6cbc4b1e7771da21840a42ef93e
3
+ metadata.gz: 562c1a532751f82c0aef77e9cbb283e074ad46d0252f85220be1c53edb332a00
4
+ data.tar.gz: b5a4b85ac83aa4b7bd980728b1ed2735faeff4d4d71d4b1744c98c92d9ff8521
5
5
  SHA512:
6
- metadata.gz: f2f8cbbf267cdf26e929677364f9a0db2cfdc1256fa231bbdf85f347cd301d8fdbd26c1b219d2faed9a94cacfd177e5aad665f291f9aafc809ab8406f4e25d32
7
- data.tar.gz: 9f1725a4250c1988960db905493ce797d66b096a6f586b3af6c3642956b3c5fb7194516d82c828f5c728b086dfe0fbc61f01ea39927a22dcf7742acad6c81a0c
6
+ metadata.gz: c6f100568de25bdafb0d8dcab796fd9d29a7a118e4383fee0331c3c110931eec4f0b95a3c10048f7f38024fcc338cdfb78ad0c4273657c57caa82d4ab78462ed
7
+ data.tar.gz: d4954f6b6b2af17fa111f22378f5dcb047f20e9bce6981c65ec8575898ea9c873d42ecc61154a6c116a5813e4c21ce5736c33c95ef2fb074e9ddb7f8f568db61
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 OceanBase Integrations
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,165 @@
1
+ # fluent-plugin-oceanbase-logs
2
+
3
+ Fluentd input plugin that periodically fetches SQL diagnostics data from [OceanBase Cloud](https://www.oceanbase.com/). Each event is one SQL execution (sample), with deduplication by `traceId`.
4
+
5
+ | `log_type` | API Path | Description |
6
+ | --- | --- | --- |
7
+ | `slow_sql` (default) | `/api/v2/.../slowSql` + samples | Slow SQL (per-execution) |
8
+ | `top_sql` | `/api/v2/.../topSql` + samples | Top SQL (per-execution) |
9
+
10
+ ## Requirements
11
+
12
+ | fluent-plugin-oceanbase-logs | fluentd | ruby |
13
+ | ---------------------------- | --------- | ------ |
14
+ | >= 0.1.0 | >= 1.8.0 | >= 2.4 |
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ gem install fluent-plugin-oceanbase-logs
20
+ ```
21
+
22
+ ## Preparation
23
+
24
+ 1. Create an AccessKey pair at [OceanBase Cloud AccessKey Management](https://console-cn.oceanbase.com/account/accessKey)
25
+ 2. Find your **Instance ID** and **Tenant ID** from the OceanBase Cloud console
26
+
27
+ ## Configuration
28
+
29
+ ### Slow SQL → file (one record per execution)
30
+
31
+ ```xml
32
+ <source>
33
+ @type oceanbase_logs
34
+ tag oceanbase.slow_sql
35
+ log_type slow_sql
36
+
37
+ access_key_id "#{ENV['OCEANBASE_ACCESS_KEY_ID']}"
38
+ access_key_secret "#{ENV['OCEANBASE_ACCESS_KEY_SECRET']}"
39
+ instance_id "#{ENV['OCEANBASE_INSTANCE_ID']}"
40
+ tenant_id "#{ENV['OCEANBASE_TENANT_ID']}"
41
+
42
+ # 服务接入点(API 地址)
43
+ endpoint api-cloud-cn.oceanbase.com
44
+ # 采集间隔(秒)与采集时间范围(秒)
45
+ fetch_interval 60
46
+ lookback_seconds 600
47
+
48
+ deduplicate true
49
+
50
+ <storage>
51
+ @type local
52
+ persistent true
53
+ path /var/log/fluentd/slow_sql_seen
54
+ </storage>
55
+ </source>
56
+
57
+ <match oceanbase.slow_sql>
58
+ @type file
59
+ path /var/log/fluentd/slow_sql
60
+ append true
61
+ <format>
62
+ @type json
63
+ </format>
64
+ <buffer>
65
+ @type file
66
+ path /var/log/fluentd/buffer/slow_sql
67
+ flush_mode interval
68
+ flush_interval 5s
69
+ </buffer>
70
+ </match>
71
+ ```
72
+
73
+ ### Parameters
74
+
75
+ #### Core
76
+
77
+ | Parameter | Type | Required | Default | Description |
78
+ | --- | --- | --- | --- | --- |
79
+ | `log_type` | enum | no | `slow_sql` | `slow_sql` or `top_sql` |
80
+ | `tag` | string | **yes** | — | Fluentd tag for emitted events |
81
+
82
+ #### Authentication
83
+
84
+ | Parameter | Type | Required | Default | Description |
85
+ | --- | --- | --- | --- | --- |
86
+ | `access_key_id` | string | **yes** | — | OceanBase Cloud AccessKey ID |
87
+ | `access_key_secret` | string | **yes** | — | OceanBase Cloud AccessKey Secret |
88
+
89
+ #### Cluster
90
+
91
+ | Parameter | Type | Required | Default | Description |
92
+ | --- | --- | --- | --- | --- |
93
+ | `instance_id` | string | **yes** | — | OceanBase cluster instance ID |
94
+ | `tenant_id` | string | **yes** | — | OceanBase tenant ID |
95
+ | `project_id` | string | no | nil | Project ID (`X-Ob-Project-Id` header) |
96
+
97
+ #### Filters
98
+
99
+ | Parameter | Type | Required | Default | Description |
100
+ | --- | --- | --- | --- | --- |
101
+ | `db_name` | string | no | nil | Filter by database name |
102
+ | `search_keyword` | string | no | nil | Search keyword in SQL text |
103
+ | `node_ip` | string | no | nil | Database node IP |
104
+ | `filter_condition` | string | no | nil | Advanced filter (e.g. `@avgCpuTime > 20`) |
105
+ | `sql_text_length` | integer | no | 65535 | Max SQL text length returned |
106
+
107
+ #### 服务接入点与采集时间(均在配置文件中配置)
108
+
109
+ | Parameter | Type | Required | Default | Description |
110
+ | --- | --- | --- | --- | --- |
111
+ | `endpoint` | string | no | `api-cloud-cn.oceanbase.com` | 服务接入点(API 地址;国际站可用 `api-cloud.oceanbase.com`) |
112
+ | `fetch_interval` | time | no | 300 (5 min) | 采集间隔(秒):每隔多久请求一次 API |
113
+ | `lookback_seconds` | integer | no | 600 (10 min) | 采集时间范围(秒):每次请求查询最近多长时间的数据 |
114
+
115
+ 可通过环境变量覆盖:`OCEANBASE_ENDPOINT`、`OCEANBASE_FETCH_INTERVAL`、`OCEANBASE_LOOKBACK_SECONDS`(参见 `example/` 与 `.env.example`)。
116
+
117
+ #### Behaviour
118
+
119
+ | Parameter | Type | Required | Default | Description |
120
+ | --- | --- | --- | --- | --- |
121
+ | `deduplicate` | bool | no | true | Skip already-seen records (by traceId) |
122
+ | `include_metadata` | bool | no | true | Attach `ob_instance_id` / `ob_tenant_id` / `ob_log_type` to records |
123
+ | `ssl_verify_peer` | bool | no | true | Verify SSL certificates |
124
+ | `http_proxy` | string | no | nil | HTTP proxy URL |
125
+
126
+ (`endpoint` 见上表「服务接入点与采集时间」。)
127
+
128
+ ## Output record fields
129
+
130
+ Each record is one SQL execution (sample). Main fields:
131
+
132
+ | Field | Type | Description |
133
+ | --- | --- | --- |
134
+ | `sqlId` | string | SQL identifier |
135
+ | `fullSqlText` | string | Complete SQL text |
136
+ | `sqlTextShort` | string | SQL text (truncated) |
137
+ | `sqlType` | string | `SELECT`, `UPDATE`, etc. |
138
+ | `dbName` | string | Database name |
139
+ | `userName` | string | User |
140
+ | `requestTime` | string | Execution timestamp (UTC) |
141
+ | `traceId` | string | Unique trace ID (used for dedup) |
142
+ | `elapsedTime` | double | Response time (ms) |
143
+ | `cpuTime` | double | CPU time (ms) |
144
+ | `executeTime` | double | Plan execution time (ms) |
145
+ | `returnRows` | long | Returned rows |
146
+ | `affectedRows` | long | Affected rows |
147
+
148
+ ## Examples
149
+
150
+ See the `example/` directory:
151
+
152
+ - `fluentd.conf` — Slow SQL to file
153
+ - `fluentd_to_file.conf` — Slow SQL + Top SQL to file
154
+ - `fluentd_to_loki.conf` — Slow SQL + Top SQL to Grafana Loki
155
+
156
+ ## Test
157
+
158
+ ```bash
159
+ bundle install
160
+ bundle exec rake test
161
+ ```
162
+
163
+ ## License
164
+
165
+ MIT
@@ -22,8 +22,6 @@ module Fluent::Plugin
22
22
 
23
23
  config_param :log_type, :enum, list: LOG_TYPE_PATHS.keys.map(&:to_sym), default: :slow_sql,
24
24
  desc: "Type of SQL diagnostics to collect: slow_sql or top_sql."
25
- config_param :fetch_samples, :bool, default: false,
26
- desc: "When true, fetch per-execution sample details for each SQL (each execution = one event)."
27
25
 
28
26
  config_param :access_key_id, :string, secret: true,
29
27
  desc: "OceanBase Cloud AccessKey ID."
@@ -62,7 +60,7 @@ module Fluent::Plugin
62
60
  desc: "Verify SSL certificates."
63
61
 
64
62
  config_param :deduplicate, :bool, default: true,
65
- desc: "Enable deduplication."
63
+ desc: "Enable deduplication (by traceId)."
66
64
  config_param :include_metadata, :bool, default: true,
67
65
  desc: "Attach instance_id / tenant_id / log_type to each record."
68
66
 
@@ -123,43 +121,10 @@ module Fluent::Plugin
123
121
  now = Time.now.utc
124
122
  start_time = (now - @lookback_seconds).strftime('%Y-%m-%dT%H:%M:%SZ')
125
123
  end_time = now.strftime('%Y-%m-%dT%H:%M:%SZ')
126
-
127
- if @fetch_samples
128
- fetch_and_emit_samples(start_time, end_time)
129
- else
130
- fetch_and_emit_list(start_time, end_time)
131
- end
124
+ fetch_and_emit_samples(start_time, end_time)
132
125
  end
133
126
 
134
- # ---- Mode 1: emit aggregated list (one record per sqlId) ----
135
- def fetch_and_emit_list(start_time, end_time)
136
- response = call_list_api(start_time, end_time)
137
- return unless response
138
-
139
- records = extract_records(response)
140
- return if records.nil? || records.empty?
141
-
142
- es = Fluent::MultiEventStream.new
143
-
144
- records.each do |record|
145
- sql_id = record['sqlId']
146
- next if sql_id.nil? || sql_id.empty?
147
-
148
- if @deduplicate
149
- dedup_key = :"list_#{sql_id}_#{start_time}"
150
- next if @seen_storage.get(dedup_key)
151
- @seen_storage.put(dedup_key, Time.now.to_i.to_s)
152
- end
153
-
154
- record = attach_metadata(record, start_time, end_time) if @include_metadata
155
- es.add(Fluent::EventTime.now, record)
156
- end
157
-
158
- router.emit_stream(@tag, es) unless es.empty?
159
- log.info "Emitted #{es.size} #{@log_type} events (#{start_time} ~ #{end_time})" if es.size > 0
160
- end
161
-
162
- # ---- Mode 2: emit per-execution samples (one record per trace) ----
127
+ # Fetch list then per-execution samples (one record per trace)
163
128
  def fetch_and_emit_samples(start_time, end_time)
164
129
  list_response = call_list_api(start_time, end_time)
165
130
  return unless list_response
@@ -236,16 +201,21 @@ module Fluent::Plugin
236
201
  end
237
202
 
238
203
  def extract_records(response)
239
- if response['data'].is_a?(Hash) && response['data']['dataList'].is_a?(Array)
240
- response['data']['dataList']
241
- elsif response['Data'].is_a?(Array)
242
- response['Data']
243
- elsif response['data'].is_a?(Array)
244
- response['data']
245
- else
246
- log.warn "Unexpected API response structure", keys: response.keys
247
- nil
204
+ data = response['data']
205
+ return [] if data.nil?
206
+
207
+ if data.is_a?(Hash)
208
+ list = data['dataList']
209
+ return list if list.is_a?(Array)
210
+ return [] if list.nil? || list == []
211
+ elsif data.is_a?(Array)
212
+ return data
248
213
  end
214
+
215
+ log.warn "Unexpected API response structure",
216
+ keys: response.keys, data_class: data.class.name,
217
+ data_keys: (data.respond_to?(:keys) ? data.keys : nil)
218
+ []
249
219
  end
250
220
 
251
221
  # ---- API calls ----
@@ -2,7 +2,7 @@ module Fluent
2
2
  module Plugin
3
3
  module OceanBase
4
4
  module Logs
5
- VERSION = "0.1.0"
5
+ VERSION = "0.1.2"
6
6
  end
7
7
  end
8
8
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-oceanbase-logs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - OceanBase Integrations
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-03-06 00:00:00.000000000 Z
11
+ date: 2026-03-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fluentd
@@ -94,14 +94,16 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '3.0'
97
- description: Periodically fetches slow SQL information from OceanBase Cloud via the
98
- DescribeOasSlowSQLList API and emits them as Fluentd events.
97
+ description: Fetches Slow SQL and Top SQL per-execution samples from OceanBase Cloud
98
+ and emits them as Fluentd events (one record per trace, dedup by traceId).
99
99
  email:
100
100
  - integrations@example.com
101
101
  executables: []
102
102
  extensions: []
103
103
  extra_rdoc_files: []
104
104
  files:
105
+ - LICENSE
106
+ - README.md
105
107
  - lib/fluent/plugin/in_oceanbase_logs.rb
106
108
  - lib/fluent/plugin/oceanbase/logs/version.rb
107
109
  homepage: https://github.com/your-org/fluent-plugin-oceanbase-logs
@@ -123,7 +125,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
123
125
  - !ruby/object:Gem::Version
124
126
  version: '0'
125
127
  requirements: []
126
- rubygems_version: 3.3.5
128
+ rubygems_version: 3.0.3.1
127
129
  signing_key:
128
130
  specification_version: 4
129
131
  summary: Fluentd input plugin for OceanBase Cloud Logs