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

feat: Add ClickHouse driver to sql inputs/outputs plugins #9671

Merged
merged 21 commits into from
Jan 28, 2022

Conversation

nahsi
Copy link
Contributor

@nahsi nahsi commented Aug 24, 2021

Required for all PRs:

Added ClickHouse to sql input drivers (using clickhouse-go)


Since there are no changes to plugin code, I'm not sure there is a need to add tests.

@telegraf-tiger
Copy link
Contributor

Thanks so much for the pull request!
🤝 ✒️ Just a reminder that the CLA has not yet been signed, and we'll need it before merging. Please sign the CLA when you get a chance, then post a comment here saying !signed-cla

@telegraf-tiger telegraf-tiger bot added the feat Improvement on an existing feature such as adding a new setting/mode to an existing plugin label Aug 24, 2021
@nahsi
Copy link
Contributor Author

nahsi commented Aug 24, 2021

!signed-cla

Copy link
Member

@srebhan srebhan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me! Thanks for adding this driver @nahsi!

@srebhan
Copy link
Member

srebhan commented Sep 7, 2021

@nahsi one additional request, can you please also prepare a pull-request for output/sql so we can keep the two symmetrical...

@srebhan
Copy link
Member

srebhan commented Sep 7, 2021

@nahsi and another request: Please add a test-case, i.e. a docker instance where you can import the example tables. Take a look at the postgres and mysql tests in the repo.

@srebhan srebhan self-assigned this Sep 7, 2021
@srebhan srebhan added area/sql plugin/input 1. Request for new input plugins 2. Issues/PRs that are related to input plugins labels Sep 7, 2021
@srebhan
Copy link
Member

srebhan commented Oct 15, 2021

@nahsi any chance you add a test-case for this database type?

@nahsi
Copy link
Contributor Author

nahsi commented Oct 15, 2021

@srebhan I will try to do it this weekend, very sorry for the delay 🙇🏼

@nahsi nahsi changed the title feat: Add ClickHouse driver to sql input plugin feat: Add ClickHouse driver to sql inputs/outputs plugins Oct 16, 2021
@nahsi
Copy link
Contributor Author

nahsi commented Oct 16, 2021

@srebhan to use clickhouse-go I had to use begin->prepare->exec->commit instead of just exec in outputs/sql.

With just exec clickhouse-go will emit this error.

I'm not sure if it is OK since I don't know golang and I know clickhouse only from OPS point of view :) But it works.

Maybe it would be better to begin then loop over metrics preparing sql etc and then commit? I don't know. If it is so I could try to update.

Copy link
Member

@srebhan srebhan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent work @nahsi, nice code and test! I have one suggestion regarding the special insert of clickhouse. My intention there is to prepare for other drivers that require special treatment by directly switch to a switch statement. What do you think?

plugins/outputs/sql/sql.go Outdated Show resolved Hide resolved
plugins/outputs/sql/sql_test.go Outdated Show resolved Hide resolved
Co-authored-by: Sven Rebhan <36194019+srebhan@users.noreply.github.com>
@srebhan
Copy link
Member

srebhan commented Nov 30, 2021

@nahsi any update on this PR?

@nahsi
Copy link
Contributor Author

nahsi commented Dec 6, 2021

Sorry, I will do it this week.

@nahsi
Copy link
Contributor Author

nahsi commented Jan 6, 2022

@srebhan I've commited your suggestions, ready for another review.

Copy link
Member

@srebhan srebhan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nahsi thanks for the update. There are some minor formatting issues, but nothing too big.

plugins/outputs/sql/sql.go Outdated Show resolved Hide resolved
plugins/outputs/sql/sql.go Outdated Show resolved Hide resolved
plugins/outputs/sql/sql.go Outdated Show resolved Hide resolved
plugins/outputs/sql/sql.go Outdated Show resolved Hide resolved
@telegraf-tiger
Copy link
Contributor

@nahsi
Copy link
Contributor Author

nahsi commented Jan 14, 2022

@srebhan I've commited the changes you suggested. Please have a look again when you have time

Copy link
Member

@srebhan srebhan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nahsi perfect thank you for your contribution!

Looks good to me.

@srebhan srebhan added the ready for final review This pull request has been reviewed and/or tested by multiple users and is ready for a final review. label Jan 24, 2022
@powersj powersj merged commit 531d7bb into influxdata:master Jan 28, 2022
@nahsi nahsi deleted the sql-clickhouse-driver branch January 29, 2022 08:02
@crabvk
Copy link

crabvk commented Feb 14, 2022

Maybe I'm doing something wrong, but I'm getting this error

2022-02-14T05:32:39Z E! [agent] Failed to connect to [outputs.sql], retrying in 15s, error was 'code: 516, message: default: Authentication failed: password is incorrect or there is no user with such name'

Using following telegraf config

[[outputs.sql]]
  driver = "clickhouse"
  data_source_name = "clickhouse://user:password@example.com:9000/database"
  [outputs.sql.convert]
    integer = "Int64"
    text = "String"
    timestamp = "DateTime"
    defaultvalue = "String"
    unsigned = "UInt64"
    bool = "Uint8"

However, from the same server I'm able to connect to clickhouse using cli

clickhouse-client --user user --password password --host example.com --database database

I've checked credentials several times, they are the same in both cases.

UPD
Oops, I was using wrong connection string from clickhouse-go v2, for v1 it has different format

data_source_name = "tcp://example.com:9000?username=user&password=password&database=database"

Now connection works.
Thank you for the plugin 🙂

@crabvk
Copy link

crabvk commented Feb 14, 2022

Got another error now

2022-02-14T06:01:11Z E! [agent] Error writing to outputs.sql: code: 62, message: Syntax error: failed at position 72 ('UInt64'): UInt64,"inactive" Int64 UInt64,"vmalloc_chunk" Int64 UInt64,"sreclaimable" Int64 UInt64,"swap_cached" Int64 UInt64,"used" Int64 UInt64,"huge_pages_free" Int64 U. Expected one of: DEFAULT, MATERIALIZED, ALIAS, NOT, NULL, COMMENT, CODEC, TTL, token, Comma, ClosingRoundBracket
Clickhouse log message 2022.02.14 06:07:46.082356 [ 2196388 ] {1ff9aa5d-c0c5-4322-8b15-5e94806715ef} TCPHandler: Code: 62. DB::Exception: Syntax error: failed at position 72 ('UInt64'): UInt64,"inactive" Int64 UInt64,"vmalloc_chunk" Int64 UInt64,"sreclaimable" Int64 UInt64,"swap_cached" Int64 UInt64,"used" Int64 UInt64,"huge_pages_free" Int64 U. Expected one of: DEFAULT, MATERIALIZED, ALIAS, NOT, NULL, COMMENT, CODEC, TTL, token, Comma, ClosingRoundBracket. (SYNTAX_ERROR), Stack trace (when copying this message, always include the lines below):
  1. DB::Exception::Exception(std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator > const&, int, bool) @ 0xa82d07a in /usr/bin/clickhouse
  2. DB::parseQueryAndMovePosition(DB::IParser&, char const*&, char const*, std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator > const&, bool, unsigned long, unsigned long) @ 0x14d642bf in /usr/bin/clickhouse
  3. ? @ 0x13d121f0 in /usr/bin/clickhouse
  4. DB::executeQuery(std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator > const&, std::__1::shared_ptrDB::Context, bool, DB::QueryProcessingStage::Enum) @ 0x13d11e55 in /usr/bin/clickhouse
  5. DB::TCPHandler::runImpl() @ 0x147f050f in /usr/bin/clickhouse
  6. DB::TCPHandler::run() @ 0x14804259 in /usr/bin/clickhouse
  7. Poco::Net::TCPServerConnection::start() @ 0x1745e52f in /usr/bin/clickhouse
  8. Poco::Net::TCPServerDispatcher::run() @ 0x17460981 in /usr/bin/clickhouse
  9. Poco::PooledThread::run() @ 0x17611609 in /usr/bin/clickhouse
  10. Poco::ThreadImpl::runnableEntry(void*) @ 0x1760ed00 in /usr/bin/clickhouse
  11. ? @ 0x7f5257a61259 in ?
  12. clone @ 0x7f525798a5e3 in ?

ClickHouse version 22.1.3.7

@crabvk
Copy link

crabvk commented Feb 14, 2022

I think the cause of the problem is here, when value type is uint64 clickhouse type becomes Int64 UInt64. The workaround is

  [outputs.sql.convert]
    integer = "BIGINT"
    unsigned = "UNSIGNED"

but it would be better setting

  [outputs.sql.convert]
    integer = "INT"
    unsigned = "INT UNSIGNED"

in the first place, because now unsigned in fact behaves more like unsigned_suffix.

Also, I've noticed that uptime column is not created in system table for the system input plugin.

@srebhan
Copy link
Member

srebhan commented Feb 16, 2022

@crabvk can you please open an Issue for your issue ;-) instead of putting the information next to this PR!?

@Okaho
Copy link

Okaho commented Sep 15, 2022

its worked for me:

[[outputs.sql]]
   driver = "clickhouse"
   data_source_name = "tcp://example.com:9000?username=user&password=password&database=database"
   timestamp_column = "timestamp"
   table_template = "CREATE TABLE IF NOT EXISTS {TABLE}({COLUMNS}) ENGINE = MergeTree() PRIMARY KEY (timestamp,host) ORDER by (timestamp,host) Partition by toYYYYMMDD(timestamp)"
   table_exists_template = "SELECT 1 FROM {TABLE} LIMIT 1"
  [outputs.sql.convert]
     integer              = "INT"
     real                 = "DOUBLE"
     text                 = "TEXT"
     timestamp            = "TIMESTAMP"
     defaultvalue         = "TEXT"
     unsigned             = "UNSIGNED"
     bool                 = "BOOL"

@Okaho
Copy link

Okaho commented Feb 21, 2023 via email

@zentkhv
Copy link

zentkhv commented Feb 21, 2023 via email

@Okaho
Copy link

Okaho commented Feb 21, 2023

telegraf --version
Telegraf 1.24.0 (git: HEAD@3c4a6516)

/etc/telegraf/telegraf.conf

[agent]
  interval = "60s"
  metric_batch_size = 100
  metric_buffer_limit = 10000
  collection_jitter = "0s"
  flush_interval = "1s"
  flush_jitter = "0s"
  precision = "0s"
  logfile = "/var/log/telegraf/telegraf.log"

  hostname = "host"
  omit_hostname = false

[[outputs.sql]]
   driver = "clickhouse"

data_source_name = "tcp://aa.bb.cc.dd:9000?username=username&password=password&database=telegraf3"

   timestamp_column = "timestamp"
   table_template = "CREATE TABLE IF NOT EXISTS {TABLE}({COLUMNS}) ENGINE = MergeTree() PRIMARY KEY (timestamp,host) ORDER by (timestamp,host) Partition by toYYYYMMDD(timestamp)"
    table_exists_template = "SELECT 1 FROM {TABLE} LIMIT 1"
  [outputs.sql.convert]
     integer              = "INT"
     real                 = "DOUBLE"
     text                 = "TEXT"
     timestamp            = "TIMESTAMP"
     defaultvalue         = "TEXT"
     unsigned             = "UNSIGNED"
     bool                 = "BOOL"


[[inputs.cpu]]
  percpu = true
  totalcpu = true
  collect_cpu_time = false
  report_active = false

[[inputs.disk]]
   mount_points = ["/"]
  ignore_fs = ["tmpfs", "devtmpfs", "devfs", "iso9660", "overlay", "aufs", "squashfs"]

/etc/telegraf/telegraf.d/ping-telegraf.conf

[[inputs.ping]]
    count = 30
    ping_interval = 2.0
    timeout = 0.9
    deadline = 58
    urls = [
    "localhost",
    "gateway"
]

ClickHouse:

SHOW CREATE TABLE telegraf3.ping
 CREATE TABLE telegraf3.ping
(
    `timestamp` DateTime,
    `host` String,
    `url` String,
    `standard_deviation_ms` Float64,
    `packets_transmitted` Int32,
    `packets_received` Int32,
    `percent_packet_loss` Float64,
    `ttl` Int32,
    `minimum_response_ms` Float64,
    `maximum_response_ms` Float64,
    `result_code` Int32,
    `average_response_ms` Float64
)
ENGINE = MergeTree
PARTITION BY toYYYYMMDD(timestamp)
PRIMARY KEY (timestamp, host)
ORDER BY (timestamp, host)
SETTINGS index_granularity = 8192

--

CREATE TABLE telegraf3.disk
(
    `timestamp` DateTime,
    `device` String,
    `fstype` String,
    `host` String,
    `mode` String,
    `path` String,
    `used_percent` Float64,
    `inodes_total` UInt32,
    `inodes_free` UInt32,
    `inodes_used` UInt32,
    `total` UInt32,
    `free` UInt32,
    `used` UInt32
)
ENGINE = MergeTree
PARTITION BY toYYYYMMDD(timestamp)
PRIMARY KEY (timestamp, host)
ORDER BY (timestamp, host)
SETTINGS index_granularity = 8192

--

CREATE TABLE telegraf3.cpu
(
    `timestamp` DateTime,
    `cpu` String,
    `host` String,
    `usage_system` Float64,
    `usage_iowait` Float64,
    `usage_irq` Float64,
    `usage_steal` Float64,
    `usage_guest_nice` Float64,
    `usage_user` Float64,
    `usage_idle` Float64,
    `usage_nice` Float64,
    `usage_softirq` Float64,
    `usage_guest` Float64
)
ENGINE = MergeTree
PARTITION BY toYYYYMMDD(timestamp)
PRIMARY KEY (timestamp, host)
ORDER BY (timestamp, host)
SETTINGS index_granularity = 8192
SELECT *
FROM telegraf3.ping
WHERE (url = 'localhost') 
LIMIT 1

┌───────────timestamp─┬─host─┬─url───────┬─standard_deviation_ms─┬─packets_transmitted─┬─packets_received─┬─percent_packet_loss─┬─ttl─┬─minimum_response_ms─┬─maximum_response_ms─┬─result_code─┬─average_response_ms─┐
│ 2022-12-11 00:00:50 │ host │ localhost │                 0.155 │                  30 │               30 │                   0 │  64 │               0.021 │               1.435 │           1 │               0.871 │
└─────────────────────┴──────┴───────────┴───────────────────────┴─────────────────────┴──────────────────┴─────────────────────┴─────┴─────────────────────┴─────────────────────┴─────────────┴─────────────────────┘

изображение

@Okaho
Copy link

Okaho commented Mar 1, 2023

@zentkhv, did you succeed?

@zentkhv
Copy link

zentkhv commented Mar 16, 2023

@Okaho , How did you understand which fields need to be added to the clickhouse table structure?
p.s. it seems from the output:
cpu,cpu=cpu0,host=server usage_idle=85.86497890295448,usage_nice=0,usage_iowait=0.10548523206751279,usage_irq=0,usage_guest_nice=0,usage_user=7.8059071729957115,usage_system=6.223628691983146,usage_guest=0,usage_softirq=0,usage_steal=0 1678926350000000000

@Okaho
Copy link

Okaho commented Mar 16, 2023

My tables were created by telegraf, the above structures are given as an example. I suggest deleting the tables. The telegraf version is very important, i have 1.24.0

@zentkhv
Copy link

zentkhv commented Mar 16, 2023

@Okaho , thank you very much! Finally I managed to write the data. I have a telegraph version 1.25.0, it writes both to a pre-created table, and can create its own.

@Okaho
Copy link

Okaho commented Mar 16, 2023

Great, very glad it worked out for you!

@Okaho
Copy link

Okaho commented Apr 7, 2023

Help me set up a route to send data to different systems. Using "routing plugin" https://www.influxdata.com/blog/telegraf-best-practices/ data stops going to both output plugin.

@majlsfiles
Copy link

@Okaho , thank you very much! Finally I managed to write the data. I have a telegraph version 1.25.0, it writes both to a pre-created table, and can create its own.

I am using telegraf 1.29.4 and ClickHouse 24.1.5.6, while everything works great I have problem that metrics are written slow and after a while buffer is full and metrics are dropped.

2024-02-21T09:31:04+01:00 D! [outputs.sql] Wrote batch of 1000 metrics in 6.234639174s

This should probably be in ms and not in seconds. Can someone please help with this issue?

@powersj
Copy link
Contributor

powersj commented Feb 21, 2024

Can someone please help with this issue?

Please use the slack of forums to get support and not comment on closed PRs. If sending 1000 metrics is slow, then consider getting a network trace to see what part of the request is taking a long time, as most of the time the output spends is using the network.

@influxdata influxdata locked as off-topic and limited conversation to collaborators Feb 21, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area/sql feat Improvement on an existing feature such as adding a new setting/mode to an existing plugin plugin/input 1. Request for new input plugins 2. Issues/PRs that are related to input plugins ready for final review This pull request has been reviewed and/or tested by multiple users and is ready for a final review.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants