Repository: apache/hertzbeat (language: java)

Issue:
[BUG] 启用 GreptimeDB 后启动失败
### Is there an existing issue for this?

- [X] I have searched the existing issues

### Current Behavior

_No response_

### Expected Behavior

_No response_

### Steps To Reproduce

# GreptimeDB 安装
```shell
docker run -d -p 4000-4003:4000-4003 \
-p 4242:4242 -v "/opt/greptimedb:/tmp/greptimedb" \
--name greptime --rm \
greptime/greptimedb standalone start \
--http-addr 0.0.0.0:4000 \
--rpc-addr 0.0.0.0:4001 \
--mysql-addr 0.0.0.0:4002 \
--postgres-addr 0.0.0.0:4003 \
--opentsdb-addr 0.0.0.0:4242
```

# 配置文件
```yml
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
server:
  port: 1157
spring:
  application:
    name: ${HOSTNAME:@hertzbeat@}${PID}
  profiles:
    active: prod
  mvc:
    static-path-pattern: /**
  jackson:
    default-property-inclusion: ALWAYS
  web:
    resources:
      static-locations:
        - classpath:/dist/
        - classpath:../dist/
  # need to disable spring boot mongodb auto config, or default mongodb connection tried and failed..
  autoconfigure:
    exclude: org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration, org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration
  freemarker:
    enabled: false


management:
  health:
    mail:
      enabled: off
  endpoints:
    web:
      exposure:
        include:
          - 'metrics'
          - 'health'
    enabled-by-default: on

sureness:
  auths:
    - digest
    - basic
    - jwt
  jwt:
    secret: 'CyaFv0bwq2Eik0jdrKUtsA6bx3sDJeFV643R
             LnfKefTjsIfJLBa2YkhEqEGtcHDTNe4CU6+9
             8tVt4bisXQ13rbN0oxhUZR73M6EByXIO+SV5
             dKhaX0csgOCTlCxq20yhmUea6H6JIpSE2Rwp'

---
spring:
  config:
    activate:
      on-profile: prod

  datasource:
    driver-class-name: org.postgresql.Driver
    username: postgres
    password: 123456
    url: jdbc:postgresql://rhel2:5432/postgres?currentSchema=hertzbeat
    hikari:
      max-lifetime: 120000

  jpa:
    database: postgresql
    hibernate:
      ddl-auto: update
    properties:
      hibernate:
        dialect: org.hibernate.dialect.PostgreSQLDialect

  # Not Require, Please config if you need email notify
  # 非必填：不使用邮箱作为警告通知可以去掉spring.mail配置
  mail:
    # Attention: this is mail server address.
    # 请注意此为邮件服务器地址：qq邮箱为 smtp.qq.com qq 企业邮箱为 smtp.exmail.qq.com
    host: smtp.qq.com
    username: tancloud@qq.com
    # Attention: this is not email account password, this requires an email authorization code
    # 请注意此非邮箱账户密码 此需填写邮箱授权码
    password: your-password
    #Attention: Tencent mail smtps 465,smtp 587
    #请注意腾讯邮箱465为smtps,587为smtp
    port: 587
    properties:
      mail:
        smtp:
          socketFactoryClass: javax.net.ssl.SSLSocketFactory
          ssl:
            enable: true

common:
  queue:
    # memory or kafka
    type: memory
    # properties when queue type is kafka
    kafka:
      servers: 127.0.0.1:9092
      metrics-data-topic: async-metrics-data
      alerts-data-topic: async-alerts-data

warehouse:
  store:
    # store history metrics data, enable only one below
    # 存储历史数据方式, 下方只能enabled启用一种方式
    jpa:
      enabled: false
      # The maximum retention time for history records, after which records will be deleted
      expire-time: 1h
      # The maximum number of history records retained, if this number is exceeded, half of the data in this configuration item will be deleted
      # (please set this configuration reasonably as history records can affect performance when it is large)
      # 历史数据的最大保留条数，超过此数量时，将会删除一半于此配量的数据（由于历史数据较大时会影响性能，请合理设置此配置）
      max-history-record-num: 6000
    victoria-metrics:
      enabled: false
      url: http://localhost:8428
      username: root
      password: root
    td-engine:
      enabled: false
      driver-class-name: com.taosdata.jdbc.rs.RestfulDriver
      url: jdbc:TAOS-RS://localhost:6041/hertzbeat
      username: root
      password: taosdata
    greptime:
      enabled: true
      endpoint: localhost:4001
    iot-db:
      enabled: false
      host: 127.0.0.1
      rpc-port: 6667
      username: root
      password: root
      # org.dromara.hertzbeat.warehouse.config.IotDbVersion: V_0_13 || V_1_0
      version: V_1_0
      query-timeout-in-ms: -1
      # 数据存储时间：默认'7776000000'（90天,单位为毫秒,-1代表永不过期）
      # data expire time, unit:ms, default '7776000000'(90 days, -1:never expire)
      expire-time: '7776000000'
    influxdb:
      enabled: false
      server-url: http://127.0.0.1:8086
      username: root
      password: root
      expire-time: '30d'
      replication: 1

    # store real-time metrics data, enable only one below
    # 存储实时数据方式, 下方只能enabled启用一种方式
    memory:
      enabled: true
      init-size: 16
    redis:
      enabled: false
      host: 127.0.0.1
      port: 6379
      password: 123456
      #redis使用数据库，默认为DB0
      db: 0

alerter:
  # custom console url
  console-url: https://console.tancloud.cn
  # 企业微信
  wework-webHook-url: https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=
  # 钉钉
  dingtalk-webhook-url: https://oapi.dingtalk.com/robot/send?access_token=
  # 飞书
  flybook-webhook-url: https://open.feishu.cn/open-apis/bot/v2/hook/
  # telegram
  telegram-bot-api-url: https://api.telegram.org/bot%s/sendMessage
  # discord
  discord-notify-url: https://discord.com/api/v9/channels/%s/messages
  # server酱
  server-chan-notify-url: https://sctapi.ftqq.com/%s.send
  # gotify
  gotify-notify-url: http://127.0.0.1/message?token=%s

scheduler:
  server:
    enabled: true
    port: 1158

```

# startup.log
```log
  _   _           _       ____             _
 | | | | ___ _ __| |_ ___| __ )  ___  __ _| |_
 | |_| |/ _ \ '__| __|_  /  _ \ / _ \/ _` | __|        Profile: prod
 |  _  |  __/ |  | |_ / /| |_) |  __/ (_| | |_         Name: rhel224063 Port: 1157 Pid: 24063
 |_| |_|\___|_|   \__/___|____/ \___|\__,_|\__|        https://hertzbeat.com/ 

2024-04-16 11:08:25 [main] INFO  org.dromara.hertzbeat.manager.Manager - Starting Manager using Java 11.0.21 on rhel2 with PID 24063 (/opt/hertzbeat/hertzbeat.jar started by root in /opt/hertzbeat)
2024-04-16 11:08:25 [main] INFO  org.dromara.hertzbeat.manager.Manager - The following 1 profile is active: "prod"
2024-04-16 11:08:25 [background-preinit] INFO  org.hibernate.validator.internal.util.Version - HV000001: Hibernate Validator 6.2.5.Final
2024-04-16 11:08:27 [main] INFO  org.springframework.data.repository.config.RepositoryConfigurationDelegate - Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2024-04-16 11:08:27 [main] INFO  org.springframework.data.repository.config.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 508 ms. Found 24 JPA repository interfaces.
2024-04-16 11:08:29 [main] INFO  org.springframework.boot.web.embedded.tomcat.TomcatWebServer - Tomcat initialized with port(s): 1157 (http)
2024-04-16 11:08:29 [main] INFO  org.apache.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-1157"]
2024-04-16 11:08:29 [main] INFO  org.apache.catalina.core.StandardService - Starting service [Tomcat]
2024-04-16 11:08:29 [main] INFO  org.apache.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/9.0.65]
2024-04-16 11:08:29 [main] INFO  org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext
2024-04-16 11:08:29 [main] INFO  org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 4531 ms
2024-04-16 11:08:29 [main] INFO  com.usthe.sureness.configuration.SurenessAutoConfiguration - [sureness-starter] - SurenessSubjectFactory init success
2024-04-16 11:08:30 [main] INFO  com.usthe.sureness.configuration.SurenessFilter - servlet surenessFilter initialized
2024-04-16 11:08:30 [main] INFO  org.hibernate.jpa.internal.util.LogHelper - HHH000204: Processing PersistenceUnitInfo [name: default]
2024-04-16 11:08:30 [main] INFO  org.hibernate.Version - HHH000412: Hibernate ORM core version 5.6.11.Final
2024-04-16 11:08:30 [main] INFO  org.hibernate.annotations.common.Version - HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
2024-04-16 11:08:31 [main] INFO  com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
2024-04-16 11:08:31 [main] INFO  cc.blynk.clickhouse.ClickHouseDriver - Driver registered
2024-04-16 11:08:31 [main] INFO  com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed.
2024-04-16 11:08:31 [main] INFO  org.hibernate.dialect.Dialect - HHH000400: Using dialect: org.hibernate.dialect.PostgreSQLDialect
2024-04-16 11:08:34 [main] INFO  org.hibernate.engine.transaction.jta.platform.internal.JtaPlatformInitiator - HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2024-04-16 11:08:34 [main] INFO  org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean - Initialized JPA EntityManagerFactory for persistence unit 'default'
2024-04-16 11:08:37 [main] INFO  org.apache.arrow.memory.BaseAllocator - Debug mode disabled.
2024-04-16 11:08:37 [main] INFO  org.apache.arrow.memory.DefaultAllocationManagerOption - allocation manager type not specified, using netty as the default type
2024-04-16 11:08:37 [main] INFO  org.apache.arrow.memory.CheckAllocator - Using DefaultAllocationManager at memory-netty-10.0.1.jar!/org/apache/arrow/memory/DefaultAllocationManagerFactory.class
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.apache.arrow.memory.util.MemoryUtil (file:/opt/hertzbeat/lib/arrow-memory-core-10.0.1.jar) to field java.nio.Buffer.address
WARNING: Please consider reporting this to the maintainers of org.apache.arrow.memory.util.MemoryUtil
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
2024-04-16 11:08:38 [main] WARN  org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'metricsDataController' defined in URL [jar:file:/opt/hertzbeat/lib/hertzbeat-warehouse-1.0.jar!/org/dromara/hertzbeat/warehouse/controller/MetricsDataController.class]: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'historyGrepTimeDbDataStorage' defined in URL [jar:file:/opt/hertzbeat/lib/hertzbeat-warehouse-1.0.jar!/org/dromara/hertzbeat/warehouse/store/HistoryGrepTimeDbDataStorage.class]: Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.dromara.hertzbeat.warehouse.store.HistoryGrepTimeDbDataStorage]: Constructor threw exception; nested exception is java.lang.IndexOutOfBoundsException: index: -1, length: 0 (expected: range(0, 48))
2024-04-16 11:08:38 [Timer-0] ERROR org.dromara.hertzbeat.push.service.impl.PushServiceImpl - periodical deletion failed. Error creating bean with name 'transactionManager': Singleton bean creation not allowed while singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)
2024-04-16 11:08:38 [metrics-task-dispatcher] INFO  org.dromara.hertzbeat.collector.dispatch.CommonDispatcher - [Dispatcher]-metrics-task-dispatcher has been interrupt to close.
2024-04-16 11:08:38 [metrics-task-dispatcher] INFO  org.dromara.hertzbeat.collector.dispatch.CommonDispatcher - Thread Interrupted, Shutdown the [metrics-task-dispatcher]
2024-04-16 11:08:38 [main] INFO  org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean - Closing JPA EntityManagerFactory for persistence unit 'default'
2024-04-16 11:08:38 [main] INFO  com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown initiated...
2024-04-16 11:08:38 [main] INFO  com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown completed.
2024-04-16 11:08:38 [main] INFO  org.apache.catalina.core.StandardService - Stopping service [Tomcat]
2024-04-16 11:08:38 [main] INFO  com.usthe.sureness.configuration.SurenessFilter - servlet surenessFilter destroyed
2024-04-16 11:08:38 [main] INFO  org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener - 

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2024-04-16 11:08:38 [main] ERROR org.springframework.boot.SpringApplication - Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'metricsDataController' defined in URL [jar:file:/opt/hertzbeat/lib/hertzbeat-warehouse-1.0.jar!/org/dromara/hertzbeat/warehouse/controller/MetricsDataController.class]: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'historyGrepTimeDbDataStorage' defined in URL [jar:file:/opt/hertzbeat/lib/hertzbeat-warehouse-1.0.jar!/org/dromara/hertzbeat/warehouse/store/HistoryGrepTimeDbDataStorage.class]: Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.dromara.hertzbeat.warehouse.store.HistoryGrepTimeDbDataStorage]: Constructor threw exception; nested exception is java.lang.IndexOutOfBoundsException: index: -1, length: 0 (expected: range(0, 48))
	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800)
	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:229)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1372)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1222)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:955)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:308)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295)
	at org.dromara.hertzbeat.manager.Manager.main(Manager.java:40)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'historyGrepTimeDbDataStorage' defined in URL [jar:file:/opt/hertzbeat/lib/hertzbeat-warehouse-1.0.jar!/org/dromara/hertzbeat/warehouse/store/HistoryGrepTimeDbDataStorage.class]: Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.dromara.hertzbeat.warehouse.store.HistoryGrepTimeDbDataStorage]: Constructor threw exception; nested exception is java.lang.IndexOutOfBoundsException: index: -1, length: 0 (expected: range(0, 48))
	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:315)
	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:296)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1372)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1222)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
	at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.addCandidateEntry(DefaultListableBeanFactory.java:1609)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1573)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveMultipleBeans(DefaultListableBeanFactory.java:1462)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1349)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1311)
	at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887)
	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791)
	... 19 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.dromara.hertzbeat.warehouse.store.HistoryGrepTimeDbDataStorage]: Constructor threw exception; nested exception is java.lang.IndexOutOfBoundsException: index: -1, length: 0 (expected: range(0, 48))
	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:224)
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:117)
	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:311)
	... 36 common frames omitted
Caused by: java.lang.IndexOutOfBoundsException: index: -1, length: 0 (expected: range(0, 48))
	at org.apache.arrow.memory.ArrowBuf.checkIndex(ArrowBuf.java:701)
	at org.apache.arrow.memory.ArrowBuf.getBytes(ArrowBuf.java:728)
	at org.apache.arrow.vector.VarCharVector.get(VarCharVector.java:116)
	at org.apache.arrow.vector.VarCharVector.getObject(VarCharVector.java:127)
	at org.apache.arrow.vector.VarCharVector.getObject(VarCharVector.java:38)
	at io.greptime.models.SelectRows$DefaultSelectRows.consume(SelectRows.java:126)
	at io.greptime.models.SelectRows$DefaultSelectRows.hasNext(SelectRows.java:161)
	at java.base/java.util.Iterator.forEachRemaining(Iterator.java:132)
	at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
	at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
	at io.greptime.models.SelectRows.collect(SelectRows.java:65)
	at org.dromara.hertzbeat.warehouse.store.HistoryGrepTimeDbDataStorage.createDatabase(HistoryGrepTimeDbDataStorage.java:119)
	at org.dromara.hertzbeat.warehouse.store.HistoryGrepTimeDbDataStorage.initDbSession(HistoryGrepTimeDbDataStorage.java:88)
	at org.dromara.hertzbeat.warehouse.store.HistoryGrepTimeDbDataStorage.<init>(HistoryGrepTimeDbDataStorage.java:73)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:211)
	... 38 common frames omitted
2024-04-16 11:08:41 [status-page-calculate-0] INFO  org.dromara.hertzbeat.manager.component.status.CalculateStatus - start to calculate status page state
2024-04-16 11:08:41 [status-page-calculate-0] ERROR org.dromara.hertzbeat.manager.component.status.CalculateStatus - status page calculate component state error: Error creating bean with name 'spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties': Could not bind properties to 'DataSourceProperties' : prefix=spring.datasource, ignoreInvalidFields=false, ignoreUnknownFields=true; nested exception is java.lang.IllegalStateException: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@78e16155 has not been refreshed yet
org.springframework.boot.context.properties.ConfigurationPropertiesBindException: Error creating bean with name 'spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties': Could not bind properties to 'DataSourceProperties' : prefix=spring.datasource, ignoreInvalidFields=false, ignoreUnknownFields=true; nested exception is java.lang.IllegalStateException: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@78e16155 has not been refreshed yet
	at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.bind(ConfigurationPropertiesBindingPostProcessor.java:92)
	at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization(ConfigurationPropertiesBindingPostProcessor.java:78)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:440)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1796)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
	at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1391)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1311)
	at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887)
	at org.springframework.beans.factory.support.ConstructorResolver.resolvePreparedArguments(ConstructorResolver.java:834)
	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:449)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
	at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1391)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1311)
	at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887)
	at org.springframework.beans.factory.support.ConstructorResolver.resolvePreparedArguments(ConstructorResolver.java:834)
	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:449)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory$1.orderedStream(DefaultListableBeanFactory.java:481)
	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.detectPersistenceExceptionTranslators(PersistenceExceptionTranslationInterceptor.java:167)
	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:149)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:174)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215)
	at com.sun.proxy.$Proxy192.findAll(Unknown Source)
	at org.dromara.hertzbeat.manager.component.status.CalculateStatus.lambda$startCalculate$1(CalculateStatus.java:86)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
	at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305)
	at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.lang.IllegalStateException: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@78e16155 has not been refreshed yet
	at org.springframework.context.support.AbstractApplicationContext.assertBeanFactoryActive(AbstractApplicationContext.java:1141)
	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1159)
	at org.springframework.boot.context.properties.BoundConfigurationProperties.get(BoundConfigurationProperties.java:78)
	at org.springframework.boot.context.properties.ConfigurationPropertiesBinder.getHandler(ConfigurationPropertiesBinder.java:133)
	at org.springframework.boot.context.properties.ConfigurationPropertiesBinder.getBindHandler(ConfigurationPropertiesBinder.java:114)
	at org.springframework.boot.context.properties.ConfigurationPropertiesBinder.bind(ConfigurationPropertiesBinder.java:94)
	at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.bind(ConfigurationPropertiesBindingPostProcessor.java:89)
	... 56 common frames omitted

```

### Environment

```markdown
HertzBeat version(s):
```


### Debug logs

_No response_

### Anything else?

_No response_


Discussion / hints:
Hi, due to the greptime api change, the latest version is no longer supported, you can use TDengine, Victoria Metrics and other databases.
Sorry for that. Greptime is still under heavy development. GreptimeDB gRPC query API was already deprecated, we recommend using JDBC for querying.

Let me create a PR to fix this issue.
> Sorry for that. Greptime is still under heavy development. GreptimeDB gRPC query API was already deprecated, we recommend using JDBC for querying.
> 
> Let me create a PR to fix this issue.

Thanks a lot

Fix patch:
diff --git a/home/docs/start/greptime-init.md b/home/docs/start/greptime-init.md
index d2b73d39068..f4a0ccbdde9 100644
--- a/home/docs/start/greptime-init.md
+++ b/home/docs/start/greptime-init.md
@@ -8,7 +8,7 @@ Apache HertzBeat (incubating)'s historical data storage relies on the time serie
 
 > It is recommended to use VictoriaMetrics as metrics storage.
 
-GreptimeDB is an open-source time-series database with a special focus on scalability, analytical capabilities and efficiency.   
+[GreptimeDB](https://github.com/GreptimeTeam/greptimedb) is an open-source time-series database with a special focus on scalability, analytical capabilities and efficiency.
 
 It's designed to work on infrastructure of the cloud era, and users benefit from its elasticity and commodity storage.
 
@@ -26,21 +26,24 @@ It's designed to work on infrastructure of the cloud era, and users benefit from
 2. Install GreptimeDB with Docker   
 
 ```shell
-$ docker run -p 4000-4004:4000-4004 \
-    -p 4242:4242 -v /opt/greptimedb:/tmp/greptimedb \
-    --name greptime \
-    greptime/greptimedb standalone start \
-    --http-addr 0.0.0.0:4000 \
-    --rpc-addr 0.0.0.0:4001 \
+$ docker run -p 127.0.0.1:4000-4003:4000-4003 \
+  -v "$(pwd)/greptimedb:/tmp/greptimedb" \
+  --name greptime --rm \
+  greptime/greptimedb:latest standalone start \
+  --http-addr 0.0.0.0:4000 \
+  --rpc-addr 0.0.0.0:4001 \
+  --mysql-addr 0.0.0.0:4002 \
+  --postgres-addr 0.0.0.0:4003
 ```
-   `-v /opt/greptimedb:/tmp/greptimedb` is local persistent mount of greptimedb data directory. `/opt/greptimedb` should be replaced with the actual local directory.
+
+   `-v "$(pwd)/greptimedb:/tmp/greptimedb"` is local persistent mount of greptimedb data directory. `$(pwd)/greptimedb` should be replaced with the actual local directory, default is the `greptimedb` directory under the current directory.
    use```$ docker ps``` to check if the database started successfully
 
 ### Configure the database connection in hertzbeat `application.yml` configuration file  
 
 1. Configure HertzBeat's configuration file   
-   Modify `hertzbeat/config/application.yml` configuration file         
-   Note⚠️The docker container way need to mount application.yml file locally, while you can use installation package way to unzip and modify `hertzbeat/config/application.yml`     
+   Modify `hertzbeat/config/application.yml` configuration file [/script/application.yml](https://github.com/apache/hertzbeat/raw/master/script/application.yml)
+   Note⚠️The docker container way need to mount application.yml file locally, while you can use installation package way to unzip and modify `hertzbeat/config/application.yml`
    Replace `warehouse.store.greptime` data source parameters, URL account and password.
 
 ```yaml
@@ -52,9 +55,15 @@ warehouse:
       # enable greptime   
       greptime:
          enabled: true
-         endpoint: localhost:4001
+         grpc-endpoints: localhost:4001
+         url: jdbc:mysql://localhost:4002/hertzbeat?connectionTimeZone=Asia/Shanghai&forceConnectionTimeZoneToSession=true
+         driver-class-name: com.mysql.cj.jdbc.Driver
+         username: greptime
+         password: greptime
 ```
 
+The default database is `hertzbeat` in the `url`.
+
 2. Restart HertzBeat
 
 ### FAQ
diff --git a/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/start/greptime-init.md b/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/start/greptime-init.md
index 5b3279b1f40..ab99977867e 100644
--- a/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/start/greptime-init.md
+++ b/home/i18n/zh-cn/docusaurus-plugin-content-docs/current/start/greptime-init.md
@@ -1,14 +1,14 @@
 ---
 id: greptime-init  
-title: 依赖时序数据库服务GreptimeDB安装初始化(可选)        
-sidebar_label: 指标数据存储GreptimeDB    
+title: 依赖时序数据库服务 GreptimeDB 安装初始化（可选）
+sidebar_label: 指标数据存储 GreptimeDB
 ---
 
 Apache HertzBeat (incubating) 的历史数据存储依赖时序数据库，任选其一安装初始化即可，也可不安装(注意⚠️但强烈建议生产环境配置)
 
 > 我们推荐使用并长期支持 VictoriaMetrics 作为存储。
 
-GreptimeDB is an open-source time-series database with a special focus on scalability, analytical capabilities and efficiency.   
+[GreptimeDB](https://github.com/GreptimeTeam/greptimedb) is an open-source time-series database with a special focus on scalability, analytical capabilities and efficiency. 
 It's designed to work on infrastructure of the cloud era, and users benefit from its elasticity and commodity storage.
 
 **⚠️ 若不配置时序数据库，则只会留最近一小时历史数据**  
@@ -25,21 +25,24 @@ It's designed to work on infrastructure of the cloud era, and users benefit from
 2. Docker安装GreptimeDB  
 
 ```shell
-$ docker run -p 4000-4004:4000-4004 \
-    -p 4242:4242 -v /opt/greptimedb:/tmp/greptimedb \
-    --name greptime \
-    greptime/greptimedb standalone start \
-    --http-addr 0.0.0.0:4000 \
-    --rpc-addr 0.0.0.0:4001 
+$ docker run -p 127.0.0.1:4000-4003:4000-4003 \
+  -v "$(pwd)/greptimedb:/tmp/greptimedb" \
+  --name greptime --rm \
+  greptime/greptimedb:latest standalone start \
+  --http-addr 0.0.0.0:4000 \
+  --rpc-addr 0.0.0.0:4001 \
+  --mysql-addr 0.0.0.0:4002 \
+  --postgres-addr 0.0.0.0:4003
 ```
 
-   `-v /opt/greptimedb:/tmp/greptimedb` 为greptimedb数据目录本地持久化挂载，需将`/opt/greptimedb`替换为实际本地存在的目录
+  `-v "$(pwd)/greptimedb:/tmp/greptimedb` 为 greptimedb 数据目录本地持久化挂载，需将 `$(pwd)/greptimedb` 替换为实际本地存在的目录，默认使用执行命令的当前目录下的 `greptimedb` 目录作为数据目录。
+
    使用```$ docker ps```查看数据库是否启动成功
 
 ### 在hertzbeat的`application.yml`配置文件配置此数据库连接   
 
 1. 配置HertzBeat的配置文件
-   修改位于 `hertzbeat/config/application.yml` 的配置文件       
+   修改位于 `hertzbeat/config/application.yml` 的配置文件 [/script/application.yml](https://github.com/apache/hertzbeat/raw/master/script/application.yml)
    注意⚠️docker容器方式需要将application.yml文件挂载到主机本地,安装包方式解压修改位于 `hertzbeat/config/application.yml` 即可     
 
 **修改里面的`warehouse.store.jpa.enabled`参数为`false`， 配置里面的`warehouse.store.greptime`数据源参数，URL账户密码，并启用`enabled`为`true`**    
@@ -52,9 +55,15 @@ warehouse:
          enabled: false
       greptime:
          enabled: true
-         endpoint: localhost:4001
+         grpc-endpoints: localhost:4001
+         url: jdbc:mysql://localhost:4002/hertzbeat?connectionTimeZone=Asia/Shanghai&forceConnectionTimeZoneToSession=true
+         driver-class-name: com.mysql.cj.jdbc.Driver
+         username: greptime
+         password: greptime
 ```
 
+默认数据库是 URL 中配置的  `hertzbeat` 。
+
 2. 重启 HertzBeat
 
 ### 常见问题   
diff --git a/manager/src/main/resources/application.yml b/manager/src/main/resources/application.yml
index e086e4952de..053008a8154 100644
--- a/manager/src/main/resources/application.yml
+++ b/manager/src/main/resources/application.yml
@@ -141,7 +141,11 @@ warehouse:
       password: taosdata
     greptime:
       enabled: false
-      endpoint: localhost:4001
+      grpc-endpoints: localhost:4001
+      url: jdbc:mysql://localhost:4002/hertzbeat?connectionTimeZone=Asia/Shanghai&forceConnectionTimeZoneToSession=true
+      driver-class-name: com.mysql.cj.jdbc.Driver
+      username: greptime
+      password: greptime
     iot-db:
       enabled: false
       host: 127.0.0.1
diff --git a/warehouse/pom.xml b/warehouse/pom.xml
index c89770e3755..0db9386496d 100644
--- a/warehouse/pom.xml
+++ b/warehouse/pom.xml
@@ -29,7 +29,8 @@
         <influxdb.version>2.23</influxdb.version>
         <spring-cloud-starter-openfeign.version>3.0.5</spring-cloud-starter-openfeign.version>
         <taos-jdbcdriver.version>3.0.0</taos-jdbcdriver.version>
-        <greptimedb.version>0.4.0</greptimedb.version>
+        <greptimedb.version>0.7.3</greptimedb.version>
+        <mysql-jdbcdriver.version>8.0.33</mysql-jdbcdriver.version>
     </properties>
     <modelVersion>4.0.0</modelVersion>
 
@@ -81,10 +82,10 @@
             <artifactId>influxdb-java</artifactId>
             <version>${influxdb.version}</version>
         </dependency>
-
+        <!-- greptimedb -->
         <dependency>
             <groupId>io.greptime</groupId>
-            <artifactId>greptimedb-protocol</artifactId>
+            <artifactId>ingester-all</artifactId>
             <version>${greptimedb.version}</version>
             <exclusions>
                 <exclusion>
@@ -105,28 +106,11 @@
                 </exclusion>
             </exclusions>
         </dependency>
+        <!-- mysql -->
         <dependency>
-            <groupId>io.greptime</groupId>
-            <artifactId>greptimedb-grpc</artifactId>
-            <version>${greptimedb.version}</version>
-            <exclusions>
-                <exclusion>
-                    <groupId>io.grpc</groupId>
-                    <artifactId>grpc-all</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>com.google.code.gson</groupId>
-                    <artifactId>gson</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>com.google.guava</groupId>
-                    <artifactId>guava</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>com.google.protobuf</groupId>
-                    <artifactId>protobuf-java</artifactId>
-                </exclusion>
-            </exclusions>
+             <groupId>mysql</groupId>
+             <artifactId>mysql-connector-java</artifactId>
+             <version>${mysql-jdbcdriver.version}</version>
         </dependency>
         <!-- kafka -->
         <dependency>
diff --git a/warehouse/src/main/java/org/apache/hertzbeat/warehouse/store/history/greptime/GrepTimeDbDataStorage.java b/warehouse/src/main/java/org/apache/hertzbeat/warehouse/store/history/greptime/GrepTimeDbDataStorage.java
deleted file mode 100644
index 4109cf025e9..00000000000
--- a/warehouse/src/main/java/org/apache/hertzbeat/warehouse/store/history/greptime/GrepTimeDbDataStorage.java
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.hertzbeat.warehouse.store.history.greptime;
-
-import io.greptime.GreptimeDB;
-import io.greptime.models.ColumnDataType;
-import io.greptime.models.Err;
-import io.greptime.models.QueryOk;
-import io.greptime.models.QueryRequest;
-import io.greptime.models.Result;
-import io.greptime.models.Row;
-import io.greptime.models.SelectExprType;
-import io.greptime.models.SelectRows;
-import io.greptime.models.SemanticType;
-import io.greptime.models.TableName;
-import io.greptime.models.TableSchema;
-import io.greptime.models.WriteOk;
-import io.greptime.models.WriteRows;
-import io.greptime.options.GreptimeOptions;
-import java.math.BigDecimal;
-import java.math.RoundingMode;
-import java.time.Duration;
-import java.time.ZonedDateTime;
-import java.time.temporal.TemporalAmount;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.arrow.flight.FlightRuntimeException;
-import org.apache.hertzbeat.common.constants.CommonConstants;
-import org.apache.hertzbeat.common.entity.dto.Value;
-import org.apache.hertzbeat.common.entity.message.CollectRep;
-import org.apache.hertzbeat.common.util.JsonUtil;
-import org.apache.hertzbeat.common.util.TimePeriodUtil;
-import org.apache.hertzbeat.warehouse.store.history.AbstractHistoryDataStorage;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.stereotype.Component;
-
-/**
- * greptimeDB data storage
- */
-@Component
-@ConditionalOnProperty(prefix = "warehouse.store.greptime", name = "enabled", havingValue = "true")
-@Slf4j
-public class GrepTimeDbDataStorage extends AbstractHistoryDataStorage {
-
-    /**
-     * storage database
-     */
-    private static final String STORAGE_DATABASE = "hertzbeat";
-    private static final String QUERY_HISTORY_SQL =
-            "SELECT CAST (ts AS Int64) ts, instance, \"%s\" FROM %s WHERE ts >= %s and monitor_id = %s order by ts desc;";
-    private static final String QUERY_HISTORY_WITH_INSTANCE_SQL =
-            "SELECT CAST (ts AS Int64) ts, instance, \"%s\" FROM %s WHERE ts >= %s and monitor_id = %s and instance = %s order by ts desc;";
-    private static final String QUERY_INSTANCE_SQL =
-            "SELECT DISTINCT instance FROM %s WHERE ts >= now() - interval '1' WEEK";
-    private static final String QUERY_HISTORY_INTERVAL_WITH_INSTANCE_SQL =
-            "SELECT first, avg ,max, min FROM (SELECT \"%s\" as first FROM %s WHERE monitor_id = %s and ts >= %s"
-                    + " and ts < %s ORDER BY ts LIMIT 1) LEFT JOIN (SELECT avg(\"%s\") as avg, min(\"%s\") as min, max(\"%s\") as max FROM %s WHERE ts >= %s and ts < %s) ON 1=1";
-    private static final String TABLE_NOT_EXIST = "not exist";
-    private static final String DATABASE_NOT_EXIST = "not exist";
-    private GreptimeDB greptimeDb;
-
-    public GrepTimeDbDataStorage(GreptimeProperties greptimeProperties) {
-        this.serverAvailable = this.initDbSession(greptimeProperties);
-    }
-
-    private boolean initDbSession(GreptimeProperties properties) {
-        String endpoint = properties.endpoint();
-        GreptimeOptions opts = GreptimeOptions.newBuilder(endpoint)
-                .writeMaxRetries(1)
-                .readMaxRetries(2)
-                .routeTableRefreshPeriodSeconds(-1)
-                .build();
-        greptimeDb = new GreptimeDB();
-        if (!greptimeDb.init(opts)) {
-            log.error("Fail to start Greptime client");
-            return false;
-        }
-        return createDatabase();
-    }
-
-    /**
-     * Checks if the database exists; if not, creates the Database.
-     */
-    private boolean createDatabase() {
-        // 查询现有数据库
-        QueryRequest showDatabases = QueryRequest.newBuilder()
-                .exprType(SelectExprType.Sql)
-                .ql("SHOW DATABASES;")
-                .build();
-        Result<QueryOk, Err> result = null;
-        try {
-            CompletableFuture<Result<QueryOk, Err>> future = greptimeDb.query(showDatabases);
-            result = future.get();
-        } catch (Exception e) {
-            log.info("TABLE_NOT_EXIST: {}", e.getMessage());
-            String msg = e.getMessage();
-            if (msg != null && !msg.contains(DATABASE_NOT_EXIST)) {
-                log.warn(msg);
-            }
-
-        }
-        // Check if the existing database includes“Hertzbeat”
-        boolean isDatabaseExist = false;
-        if (result != null && result.isOk()) {
-            QueryOk queryOk = result.getOk();
-            SelectRows rows = queryOk.getRows();
-            List<Row> rowsList = rows.collect();
-            for (Row row : rowsList) {
-                for (io.greptime.models.Value value : row.values()) {
-                    if (STORAGE_DATABASE.equals(value.value().toString())) {
-                        log.info("Exist Database {}", STORAGE_DATABASE);
-                        isDatabaseExist = true;
-                        break;
-                    }
-                }
-            }
-        }
-        // If it does not exist, create database
-        if (!isDatabaseExist) {
-            QueryRequest createDatabase = QueryRequest.newBuilder()
-                    .exprType(SelectExprType.Sql)
-                    .ql("CREATE DATABASE %s;", STORAGE_DATABASE)
-                    .build();
-            try {
-                CompletableFuture<Result<QueryOk, Err>> createFuture = greptimeDb.query(createDatabase);
-                isDatabaseExist = createFuture.get().isOk();
-                log.info("Database {} does not exist,and has been created", STORAGE_DATABASE);
-            } catch (InterruptedException | ExecutionException e) {
-                log.error("Error creating database");
-            }
-        }
-        return isDatabaseExist;
-    }
-
-    @Override
-    public void saveData(CollectRep.MetricsData metricsData) {
-        if (!isServerAvailable() || metricsData.getCode() != CollectRep.Code.SUCCESS) {
-            return;
-        }
-        if (metricsData.getValuesList().isEmpty()) {
-            log.info("[warehouse greptime] flush metrics data {} is null, ignore.", metricsData.getId());
-            return;
-        }
-        String monitorId = String.valueOf(metricsData.getId());
-        String table = metricsData.getApp() + "_" + metricsData.getMetrics();
-        TableSchema.Builder tableSchemaBuilder = TableSchema.newBuilder(TableName.with(STORAGE_DATABASE, table));
-
-        List<SemanticType> semanticTypes = new LinkedList<>(Arrays.asList(SemanticType.Tag, SemanticType.Tag, SemanticType.Timestamp));
-        List<ColumnDataType> dataTypes = new LinkedList<>(Arrays.asList(ColumnDataType.String, ColumnDataType.String, ColumnDataType.TimestampMillisecond));
-        List<String> columnNames = new LinkedList<>(Arrays.asList("monitor_id", "instance", "ts"));
-
-        List<CollectRep.Field> fieldsList = metricsData.getFieldsList();
-        for (CollectRep.Field field : fieldsList) {
-            semanticTypes.add(SemanticType.Field);
-            columnNames.add(field.getName());
-            // handle field type
-            if (field.getType() == CommonConstants.TYPE_NUMBER) {
-                dataTypes.add(ColumnDataType.Float64);
-            } else if (field.getType() == CommonConstants.TYPE_STRING) {
-                dataTypes.add(ColumnDataType.String);
-            }
-        }
-        tableSchemaBuilder.semanticTypes(semanticTypes.toArray(new SemanticType[0]));
-        tableSchemaBuilder.dataTypes(dataTypes.toArray(new ColumnDataType[0]));
-        tableSchemaBuilder.columnNames(columnNames.toArray(new String[0]));
-        WriteRows rows = WriteRows.newBuilder(tableSchemaBuilder.build()).build();
-        try {
-            long now = System.currentTimeMillis();
-            Object[] values = new Object[3 + fieldsList.size()];
-            values[0] = monitorId;
-            values[2] = now;
-            for (CollectRep.ValueRow valueRow : metricsData.getValuesList()) {
-                Map<String, String> labels = new HashMap<>(8);
-                for (int i = 0; i < fieldsList.size(); i++) {
-                    if (!CommonConstants.NULL_VALUE.equals(valueRow.getColumns(i))) {
-                        CollectRep.Field field = fieldsList.get(i);
-                        if (field.getType() == CommonConstants.TYPE_NUMBER) {
-                            values[3 + i] = Double.parseDouble(valueRow.getColumns(i));
-                        } else if (field.getType() == CommonConstants.TYPE_STRING) {
-                            values[3 + i] = valueRow.getColumns(i);
-                        }
-                        if (field.getLabel()) {
-                            labels.put(field.getName(), String.valueOf(values[3 + i]));
-                        }
-                    } else {
-                        values[3 + i] = null;
-                    }
-                }
-                values[1] = JsonUtil.toJson(labels);
-                rows.insert(values);
-            }
-            rows.finish();
-            CompletableFuture<Result<WriteOk, Err>> writeFuture = greptimeDb.write(rows);
-            try {
-                Result<WriteOk, Err> result = writeFuture.get(10, TimeUnit.SECONDS);
-                if (result.isOk()) {
-                    log.debug("[warehouse greptime]-Write successful");
-                } else {
-                    log.warn("[warehouse greptime]--Write failed: {}", result.getErr().getFailedQl());
-                }
-            } catch (Throwable throwable) {
-                log.error("[warehouse greptime]--Error occurred: {}", throwable.getMessage());
-            }
-        } catch (Exception e) {
-            log.error(e.getMessage(), e);
-        }
-    }
-
-    @Override
-    public Map<String, List<Value>> getHistoryMetricData(Long monitorId, String app, String metrics, String metric,
-                                                         String label, String history) {
-        Map<String, List<Value>> instanceValuesMap = new HashMap<>(8);
-        if (!isServerAvailable()) {
-            log.error("\n\t---------------Greptime Init Failed---------------\n"
-                    + "\t--------------Please Config Greptime--------------\n"
-                    + "\t----------Can Not Use Metric History Now----------\n");
-            return instanceValuesMap;
-        }
-        long expireTime = getExpireTimeFromToken(history);
-        String table = app + "_" + metrics;
-        String selectSql = label == null
-                ? String.format(QUERY_HISTORY_SQL, metric, table, expireTime, monitorId)
-                : String.format(QUERY_HISTORY_WITH_INSTANCE_SQL, metric, table, expireTime, monitorId, label);
-        log.debug("selectSql: {}", selectSql);
-        QueryRequest request = QueryRequest.newBuilder()
-                .exprType(SelectExprType.Sql)
-                .databaseName(STORAGE_DATABASE)
-                .ql(selectSql)
-                .build();
-        try {
-            CompletableFuture<Result<QueryOk, Err>> future = greptimeDb.query(request);
-            Result<QueryOk, Err> result = future.get();
-            if (result != null && result.isOk()) {
-                QueryOk queryOk = result.getOk();
-                SelectRows rows = queryOk.getRows();
-                List<Map<String, Object>> maps = rows.collectToMaps();
-                List<Value> valueList;
-                for (Map<String, Object> map : maps) {
-                    String instanceValue = map.get("instance") == null ? "" : map.get("instance").toString();
-                    Object valueObj = map.get(metric);
-                    if (valueObj == null) {
-                        continue;
-                    }
-                    String strValue = new BigDecimal(valueObj.toString()).setScale(4, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString();
-                    valueList = instanceValuesMap.computeIfAbsent(instanceValue, k -> new LinkedList<>());
-                    valueList.add(new Value(strValue, (long) map.get("ts")));
-                }
-            }
-        } catch (FlightRuntimeException e) {
-            String msg = e.getMessage();
-            if (msg != null && msg.contains(TABLE_NOT_EXIST)) {
-                List<Value> valueList = instanceValuesMap.computeIfAbsent(metric, k -> new LinkedList<>());
-                valueList.add(new Value(null, System.currentTimeMillis()));
-                log.info("[warehouse greptime]-TABLE_NOT_EXIST: {}", table);
-            }
-        } catch (Exception e) {
-            log.error(e.getMessage(), e);
-        }
-        return instanceValuesMap;
-    }
-
-    private long getExpireTimeFromToken(String history) {
-        long expireTime;
-        try {
-            TemporalAmount temporalAmount = TimePeriodUtil.parseTokenTime(history);
-            ZonedDateTime dateTime = ZonedDateTime.now().minus(temporalAmount);
-            expireTime = dateTime.toEpochSecond() * 1000L;
-        } catch (Exception e) {
-            log.error("parse history time error: {}. use default: 6h", e.getMessage());
-            ZonedDateTime dateTime = ZonedDateTime.now().minus(Duration.ofHours(6));
-            expireTime = dateTime.toEpochSecond() * 1000L;
-        }
-        return expireTime;
-    }
-
-    @Override
-    public Map<String, List<Value>> getHistoryIntervalMetricData(Long monitorId, String app, String metrics,
-                                                                 String metric, String label, String history) {
-        Map<String, List<Value>> instanceValuesMap = new HashMap<>(8);
-        if (!isServerAvailable()) {
-            log.error("\n\t---------------Greptime Init Failed---------------\n"
-                    + "\t--------------Please Config Greptime--------------\n"
-                    + "\t----------Can Not Use Metric History Now----------\n");
-            return instanceValuesMap;
-        }
-        String table = app + "_" + metrics;
-        List<String> instances = new LinkedList<>();
-        if (label != null) {
-            instances.add(label);
-        }
-        if (instances.isEmpty()) {
-            String selectSql = String.format(QUERY_INSTANCE_SQL, table);
-            log.debug("selectSql: {}", selectSql);
-            QueryRequest request = QueryRequest.newBuilder()
-                    .exprType(SelectExprType.Sql)
-                    .databaseName(STORAGE_DATABASE)
-                    .ql(selectSql)
-                    .build();
-            try {
-                CompletableFuture<Result<QueryOk, Err>> future = greptimeDb.query(request);
-                Result<QueryOk, Err> result = future.get();
-                if (result != null && result.isOk()) {
-                    QueryOk queryOk = result.getOk();
-                    SelectRows rows = queryOk.getRows();
-                    while (rows.hasNext()) {
-                        Row row = rows.next();
-                        if (row != null) {
-                            List<io.greptime.models.Value> values = row.values();
-                            for (io.greptime.models.Value value : values) {
-                                log.debug("value:{}", value.value());
-                                Object instanceValue = value.value();
-                                if (instanceValue == null || "".equals(instanceValue)) {
-                                    instances.add("''");
-                                } else {
-                                    instances.add(instanceValue.toString());
-                                }
-                            }
-                        }
-
-                    }
-                }
-            } catch (FlightRuntimeException e) {
-                String msg = e.getMessage();
-                if (msg != null && msg.contains(TABLE_NOT_EXIST)) {
-                    log.info("[warehouse greptime]-TABLE_NOT_EXIST: {}", table);
-                }
-            } catch (Exception e) {
-                log.error(e.getMessage(), e);
-            }
-        }
-        // TODO 'greptime' did not find the proper SQL function processing, temporarily using code implementation, future 'greptime' update documents using SQL implementation
-        long endTime;
-        long startTime = getExpireTimeFromToken(history);
-
-        Calendar cal = Calendar.getInstance();
-
-        long interval = System.currentTimeMillis() - startTime;
-        long fourHourCount = TimeUnit.MILLISECONDS.toHours(interval) / 4;
-        for (int i = 0; i < fourHourCount; i++) {
-            cal.clear();
-            cal.setTimeInMillis(startTime);
-            cal.add(Calendar.HOUR_OF_DAY, 4);
-            endTime = cal.getTimeInMillis();
-
-            for (String instanceValue : instances) {
-                String selectSql = String.format(QUERY_HISTORY_INTERVAL_WITH_INSTANCE_SQL, metric, table, monitorId, startTime, endTime, metric, metric, metric, table, startTime, endTime);
-
-                log.debug("selectSql: {}", selectSql);
-                QueryRequest request = QueryRequest.newBuilder()
-                        .exprType(SelectExprType.Sql)
-                        .databaseName(STORAGE_DATABASE)
-                        .ql(selectSql)
-                        .build();
-                List<Value> values = instanceValuesMap.computeIfAbsent(instanceValue, k -> new LinkedList<>());
-                try {
-                    CompletableFuture<Result<QueryOk, Err>> future = greptimeDb.query(request);
-                    Result<QueryOk, Err> result = future.get();
-                    log.debug("result:{}", result);
-                    if (result != null && result.isOk()) {
-                        QueryOk queryOk = result.getOk();
-                        SelectRows rows = queryOk.getRows();
-                        String[] col = new String[4];
-                        while (rows.hasNext()) {
-                            Row row = rows.next();
-                            if (!row.values().isEmpty()) {
-                                for (int j = 0; j < row.values().size(); j++) {
-                                    log.debug("value:{}", row.values().get(j));
-                                    String colStr = new BigDecimal(row.values().get(j).value().toString()).setScale(4, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString();
-                                    col[j] = colStr;
-                                }
-                                Value valueBuild = Value.builder()
-                                        .origin(col[0]).mean(col[1])
-                                        .min(col[2]).max(col[3])
-                                        .time(System.currentTimeMillis())
-                                        .build();
-                                values.add(valueBuild);
-                            }
-                        }
-                        log.debug("[warehouse greptime] values:{}", values);
-                    }
-                } catch (FlightRuntimeException e) {
-                    String msg = e.getMessage();
-                    if (msg != null && msg.contains(TABLE_NOT_EXIST)) {
-                        List<Value> valueList = instanceValuesMap.computeIfAbsent(metric, k -> new LinkedList<>());
-                        valueList.add(new Value(null, System.currentTimeMillis()));
-                        log.info("[warehouse greptime]-TABLE_NOT_EXIST: {}", table);
-                    }
-                } catch (Exception e) {
-                    log.error(e.getMessage(), e);
-                }
-            }
-            startTime = endTime;
-        }
-
-        return instanceValuesMap;
-    }
-
-    @Override
-    public void destroy() {
-        if (this.greptimeDb != null) {
-            this.greptimeDb.shutdownGracefully();
-        }
-    }
-}
diff --git a/warehouse/src/main/java/org/apache/hertzbeat/warehouse/store/history/greptime/GreptimeDbDataStorage.java b/warehouse/src/main/java/org/apache/hertzbeat/warehouse/store/history/greptime/GreptimeDbDataStorage.java
new file mode 100644
index 00000000000..a44417121c0
--- /dev/null
+++ b/warehouse/src/main/java/org/apache/hertzbeat/warehouse/store/history/greptime/GreptimeDbDataStorage.java
@@ -0,0 +1,423 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hertzbeat.warehouse.store.history.greptime;
+
+import com.mysql.cj.jdbc.Driver;
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
+import io.greptime.GreptimeDB;
+import io.greptime.models.AuthInfo;
+import io.greptime.models.DataType;
+import io.greptime.models.Err;
+import io.greptime.models.Result;
+import io.greptime.models.Table;
+import io.greptime.models.TableSchema;
+import io.greptime.models.WriteOk;
+import io.greptime.options.GreptimeOptions;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.DriverPropertyInfo;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.hertzbeat.common.constants.CommonConstants;
+import org.apache.hertzbeat.common.entity.dto.Value;
+import org.apache.hertzbeat.common.entity.message.CollectRep;
+import org.apache.hertzbeat.common.util.JsonUtil;
+import org.apache.hertzbeat.warehouse.store.history.AbstractHistoryDataStorage;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Component;
+
+/**
+ * GreptimeDB data storage, only supports GreptimeDB version >= v0.5
+ *
+ */
+@Component
+@ConditionalOnProperty(prefix = "warehouse.store.greptime", name = "enabled", havingValue = "true")
+@Slf4j
+public class GreptimeDbDataStorage extends AbstractHistoryDataStorage {
+
+    private static final String QUERY_HISTORY_SQL = "SELECT CAST (ts AS Int64) ts, instance, `%s` FROM `%s` WHERE ts >= now() -  interval '%s' and monitor_id = %s order by ts desc;";
+
+    @SuppressWarnings("checkstyle:LineLength")
+    private static final String QUERY_HISTORY_WITH_INSTANCE_SQL = "SELECT CAST (ts AS Int64) ts, instance, `%s` FROM `%s` WHERE ts >= now() - interval '%s' and monitor_id = %s and instance = '%s' order by ts desc;";
+
+    private static final String QUERY_INSTANCE_SQL = "SELECT DISTINCT instance FROM `%s` WHERE ts >= now() - interval '1 WEEK'";
+
+    @SuppressWarnings("checkstyle:LineLength")
+    private static final String QUERY_HISTORY_INTERVAL_WITH_INSTANCE_SQL = "SELECT CAST (ts AS Int64) ts, first_value(`%s`) range '4h' first, avg(`%s`) range '4h' avg, min(`%s`) range '4h' min, max(`%s`) range '4h' max FROM `%s` WHERE instance = '%s' AND ts >= now() - interval '%s' ALIGN '4h'";
+
+    private static final String TABLE_NOT_EXIST = "not found";
+
+    private static final String CONSTANTS_CREATE_DATABASE = "CREATE DATABASE IF NOT EXISTS `%s`";
+
+    private static final Runnable INSTANCE_EXCEPTION_PRINT = () -> {
+	if (log.isErrorEnabled()) {
+	    log.error("""
+	    	\t---------------GreptimeDB Init Failed---------------
+	    	\t--------------Please Config GreptimeDB--------------
+	    	t-----------Can Not Use Metric History Now-----------
+	    	""");
+	}
+    };
+
+    private HikariDataSource hikariDataSource;
+
+    private GreptimeDB greptimeDb;
+
+    public GreptimeDbDataStorage(GreptimeProperties greptimeProperties) {
+	if (greptimeProperties == null) {
+	    log.error("init error, please config Warehouse GreptimeDB props in application.yml");
+	    throw new IllegalArgumentException("please config Warehouse GreptimeDB props");
+	}
+	
+	serverAvailable = initGreptimeDbClient(greptimeProperties) && initGreptimeDbDataSource(greptimeProperties);
+    }
+
+    private void initGreptimeDb(final GreptimeProperties greptimeProperties) throws SQLException {
+	final DriverPropertyInfo[] properties = new Driver().getPropertyInfo(greptimeProperties.url(), null);
+	final String host = ObjectUtils.requireNonEmpty(properties[0].value);
+	final String port = ObjectUtils.requireNonEmpty(properties[1].value);
+	final String dbName = ObjectUtils.requireNonEmpty(properties[2].value);
+
+	try (final Connection tempConnection = DriverManager.getConnection("jdbc:mysql://" + host + ":" + port,
+		greptimeProperties.username(), greptimeProperties.password());
+		final PreparedStatement pstmt = tempConnection
+			.prepareStatement(String.format(CONSTANTS_CREATE_DATABASE, dbName))) {
+	    log.info("[warehouse greptime] try to create database `{}` if not exists", dbName);
+	    pstmt.execute();
+	}
+    }
+
+    private boolean initGreptimeDbClient(GreptimeProperties greptimeProperties) {
+	String endpoints = greptimeProperties.grpcEndpoints();
+	try {
+	    final DriverPropertyInfo[] properties = new Driver().getPropertyInfo(greptimeProperties.url(), null);
+	    final String dbName = ObjectUtils.requireNonEmpty(properties[2].value);
+	   
+	    GreptimeOptions opts = GreptimeOptions.newBuilder(endpoints.split(","), dbName) //
+		    .writeMaxRetries(3) //
+		    .authInfo(new AuthInfo(greptimeProperties.username(), greptimeProperties.password()))
+		    .routeTableRefreshPeriodSeconds(30) //
+		    .build();
+
+	    this.greptimeDb = GreptimeDB.create(opts);
+	} catch (Exception e) {
+	    log.error("[warehouse greptime] Fail to start GreptimeDB client");
+	    return false;
+	}
+
+	return true;
+    }
+
+    private boolean initGreptimeDbDataSource(final GreptimeProperties greptimeProperties) {
+	try {
+	    initGreptimeDb(greptimeProperties);
+	} catch (Exception e) {
+	    if (log.isErrorEnabled()) {
+		log.error(e.getMessage(), e);
+	    }
+
+	    INSTANCE_EXCEPTION_PRINT.run();
+	    return false;
+	}
+
+	final HikariConfig config = new HikariConfig();
+	// jdbc properties
+	config.setJdbcUrl(greptimeProperties.url());
+	config.setUsername(greptimeProperties.username());
+	config.setPassword(greptimeProperties.password());
+	config.setDriverClassName(greptimeProperties.driverClassName());
+	// minimum number of idle connection
+	config.setMinimumIdle(10);
+	// maximum number of connection in the pool
+	config.setMaximumPoolSize(10);
+	// maximum wait milliseconds for get connection from pool
+	config.setConnectionTimeout(30000);
+	// maximum lifetime for each connection
+	config.setMaxLifetime(0);
+	// max idle time for recycle idle connection
+	config.setIdleTimeout(0);
+	// validation query
+	config.setConnectionTestQuery("select 1");
+	try {
+	    this.hikariDataSource = new HikariDataSource(config);
+	} catch (Exception e) {
+	    INSTANCE_EXCEPTION_PRINT.run();
+	    return false;
+	}
+	return true;
+    }
+
+    @Override
+    public void saveData(CollectRep.MetricsData metricsData) {
+	if (!isServerAvailable() || metricsData.getCode() != CollectRep.Code.SUCCESS) {
+	    return;
+	}
+	if (metricsData.getValuesList().isEmpty()) {
+	    log.info("[warehouse greptime] flush metrics data {} is null, ignore.", metricsData.getId());
+	    return;
+	}
+	String monitorId = String.valueOf(metricsData.getId());
+	String tableName = getTableName(metricsData.getApp(), metricsData.getMetrics());
+	TableSchema.Builder tableSchemaBuilder = TableSchema.newBuilder(tableName);
+
+	tableSchemaBuilder.addTag("monitor_id", DataType.String) //
+		.addTag("instance", DataType.String) //
+		.addTimestamp("ts", DataType.TimestampMillisecond);
+
+	List<CollectRep.Field> fieldsList = metricsData.getFieldsList();
+	for (CollectRep.Field field : fieldsList) {
+	    // handle field type
+	    if (field.getType() == CommonConstants.TYPE_NUMBER) {
+		tableSchemaBuilder.addField(field.getName(), DataType.Float64);
+	    } else if (field.getType() == CommonConstants.TYPE_STRING) {
+		tableSchemaBuilder.addField(field.getName(), DataType.String);
+	    }
+	}
+	Table table = Table.from(tableSchemaBuilder.build());
+
+	try {
+	    long now = System.currentTimeMillis();
+	    Object[] values = new Object[3 + fieldsList.size()];
+	    values[0] = monitorId;
+	    values[2] = now;
+	    for (CollectRep.ValueRow valueRow : metricsData.getValuesList()) {
+		Map<String, String> labels = new HashMap<>(8);
+		for (int i = 0; i < fieldsList.size(); i++) {
+		    if (!CommonConstants.NULL_VALUE.equals(valueRow.getColumns(i))) {
+			CollectRep.Field field = fieldsList.get(i);
+			if (field.getType() == CommonConstants.TYPE_NUMBER) {
+			    values[3 + i] = Double.parseDouble(valueRow.getColumns(i));
+			} else if (field.getType() == CommonConstants.TYPE_STRING) {
+			    values[3 + i] = valueRow.getColumns(i);
+			}
+			if (field.getLabel()) {
+			    labels.put(field.getName(), String.valueOf(values[3 + i]));
+			}
+		    } else {
+			values[3 + i] = null;
+		    }
+		}
+		values[1] = JsonUtil.toJson(labels);
+		table.addRow(values);
+	    }
+
+	    CompletableFuture<Result<WriteOk, Err>> writeFuture = greptimeDb.write(table);
+	    try {
+		Result<WriteOk, Err> result = writeFuture.get(10, TimeUnit.SECONDS);
+		if (result.isOk()) {
+		    log.debug("[warehouse greptime]-Write successful");
+		} else {
+		    log.warn("[warehouse greptime]--Write failed: {}", result.getErr());
+		}
+	    } catch (Throwable throwable) {
+		log.error("[warehouse greptime]--Error occurred: {}", throwable.getMessage());
+	    }
+	} catch (Exception e) {
+	    log.error("[warehouse greptime]--Error: {}", e.getMessage(), e);
+	}
+    }
+
+    @Override
+    public Map<String, List<Value>> getHistoryMetricData(Long monitorId, String app, String metrics, String metric,
+	    String label, String history) {
+	Map<String, List<Value>> instanceValuesMap = new HashMap<>(8);
+	if (!isServerAvailable()) {
+	    INSTANCE_EXCEPTION_PRINT.run();
+	    return instanceValuesMap;
+	}
+
+	String table = getTableName(app, metrics);
+
+	String interval = history2interval(history);
+	String selectSql = label == null ? String.format(QUERY_HISTORY_SQL, metric, table, interval, monitorId)
+		: String.format(QUERY_HISTORY_WITH_INSTANCE_SQL, metric, table, interval, monitorId, label);
+
+	if (log.isDebugEnabled()) {
+	    log.debug("[warehouse greptime] getHistoryMetricData SQL: {}", selectSql);
+	}
+
+	try (Connection connection = hikariDataSource.getConnection();
+		Statement statement = connection.createStatement();
+		ResultSet resultSet = statement.executeQuery(selectSql)) {
+	    while (resultSet.next()) {
+		long ts = resultSet.getLong(1);
+		if (ts == 0) {
+		    if (log.isErrorEnabled()) {
+			log.error("[warehouse greptime] getHistoryMetricData query result timestamp is 0, ignore. {}.",
+				selectSql);
+		    }
+		    continue;
+		}
+		String instanceValue = resultSet.getString(2);
+		if (instanceValue == null || "".equals(instanceValue)) {
+		    instanceValue = "";
+		}
+		double value = resultSet.getDouble(3);
+		String strValue = double2decimalString(value);
+
+		List<Value> valueList = instanceValuesMap.computeIfAbsent(instanceValue, k -> new LinkedList<>());
+		valueList.add(new Value(strValue, ts));
+	    }
+	    return instanceValuesMap;
+	} catch (SQLException sqlException) {
+	    String msg = sqlException.getMessage();
+	    if (msg != null && !msg.contains(TABLE_NOT_EXIST)) {
+		if (log.isWarnEnabled()) {
+		    log.warn("[warehouse greptime] failed to getHistoryMetricData: " + sqlException.getMessage());
+		}
+	    }
+	} catch (Exception e) {
+	    if (log.isErrorEnabled()) {
+		log.error("[warehouse greptime] failed to getHistoryMetricData:" + e.getMessage(), e);
+	    }
+	}
+	return instanceValuesMap;
+    }
+
+    private String getTableName(String app, String metrics) {
+	return app + "_" + metrics;
+    }
+
+    @Override
+    public Map<String, List<Value>> getHistoryIntervalMetricData(Long monitorId, String app, String metrics,
+	    String metric, String label, String history) {
+	if (!isServerAvailable()) {
+	    INSTANCE_EXCEPTION_PRINT.run();
+	    return Collections.emptyMap();
+	}
+	String table = getTableName(app, metrics);
+	List<String> instances = new LinkedList<>();
+	if (label != null && !"".equals(label)) {
+	    instances.add(label);
+	}
+	if (instances.isEmpty()) {
+	    String selectSql = String.format(QUERY_INSTANCE_SQL, table);
+	    if (log.isDebugEnabled()) {
+		log.debug("[warehouse greptime] getHistoryIntervalMetricData sql: {}", selectSql);
+	    }
+
+	    try (Connection connection = hikariDataSource.getConnection();
+		    Statement statement = connection.createStatement();
+		    ResultSet resultSet = statement.executeQuery(selectSql)) {
+		while (resultSet.next()) {
+		    String instanceValue = resultSet.getString(1);
+		    if (instanceValue == null || "".equals(instanceValue)) {
+			instances.add("''");
+		    } else {
+			instances.add(instanceValue);
+		    }
+		}
+	    } catch (Exception e) {
+		if (log.isErrorEnabled()) {
+		    log.error("[warehouse greptime] failed to query instances" + e.getMessage(), e);
+		}
+	    }
+	}
+
+	Map<String, List<Value>> instanceValuesMap = new HashMap<>(instances.size());
+	for (String instanceValue : instances) {
+	    String selectSql = String.format(QUERY_HISTORY_INTERVAL_WITH_INSTANCE_SQL, metric, metric, metric, metric,
+		    table, instanceValue, history2interval(history));
+
+	    if (log.isDebugEnabled()) {
+		log.debug("[warehouse greptime] getHistoryIntervalMetricData sql: {}", selectSql);
+	    }
+
+	    List<Value> values = instanceValuesMap.computeIfAbsent(instanceValue, k -> new LinkedList<>());
+	    try (Connection connection = hikariDataSource.getConnection();
+		    Statement statement = connection.createStatement();
+		    ResultSet resultSet = statement.executeQuery(selectSql);) {
+		while (resultSet.next()) {
+		    long ts = resultSet.getLong(1);
+		    if (ts == 0) {
+			if (log.isErrorEnabled()) {
+			    log.error(
+				    "[warehouse greptime] getHistoryIntervalMetricData query result timestamp is 0, ignore. {}.",
+				    selectSql);
+			}
+			continue;
+		    }
+		    double origin = resultSet.getDouble(2);
+		    String originStr = double2decimalString(origin);
+		    double avg = resultSet.getDouble(3);
+		    String avgStr = double2decimalString(avg);
+		    double min = resultSet.getDouble(4);
+		    String minStr = double2decimalString(min);
+		    double max = resultSet.getDouble(5);
+		    String maxStr = double2decimalString(max);
+		    Value value = Value.builder().origin(originStr).mean(avgStr).min(minStr).max(maxStr).time(ts)
+			    .build();
+		    values.add(value);
+		}
+		resultSet.close();
+	    } catch (Exception e) {
+		if (log.isErrorEnabled()) {
+		    log.error("[warehouse greptime] failed to getHistoryIntervalMetricData: " + e.getMessage(), e);
+		}
+	    }
+	}
+	return instanceValuesMap;
+    }
+
+    // TODO(dennis): we can remove it when
+    // https://github.com/GreptimeTeam/greptimedb/issues/4168 is fixed.
+    // default 6h-6 hours: s-seconds, M-minutes, h-hours, d-days, w-weeks
+    private String history2interval(String history) {
+	if (history == null) {
+	    return null;
+	}
+	history = history.trim().toLowerCase();
+
+	// Be careful, the order matters.
+	return history.replaceAll("d", " day") //
+		.replaceAll("s", " second") //
+		.replaceAll("w", " week") //
+		.replaceAll("h", " hour")//
+		.replaceAll("m", " minute");
+    }
+
+    private String double2decimalString(double d) {
+	return BigDecimal.valueOf(d).setScale(4, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString();
+    }
+
+    @Override
+    public void destroy() {
+	if (this.greptimeDb != null) {
+	    this.greptimeDb.shutdownGracefully();
+	    this.greptimeDb = null;
+	}
+	if (this.hikariDataSource != null) {
+	    this.hikariDataSource.close();
+	    hikariDataSource = null;
+	}
+    }
+}
diff --git a/warehouse/src/main/java/org/apache/hertzbeat/warehouse/store/history/greptime/GreptimeProperties.java b/warehouse/src/main/java/org/apache/hertzbeat/warehouse/store/history/greptime/GreptimeProperties.java
index 0561af78d9c..ac8e29f9f36 100644
--- a/warehouse/src/main/java/org/apache/hertzbeat/warehouse/store/history/greptime/GreptimeProperties.java
+++ b/warehouse/src/main/java/org/apache/hertzbeat/warehouse/store/history/greptime/GreptimeProperties.java
@@ -25,7 +25,7 @@
  */
 @ConfigurationProperties(prefix = "warehouse.store.greptime")
 public record GreptimeProperties(@DefaultValue("false") boolean enabled,
-                                 @DefaultValue("127.0.0.1:4001") String endpoint,
-                                 String username,
-                                 String password) {
+	@DefaultValue("127.0.0.1:4001") String grpcEndpoints,
+	@DefaultValue("jdbc:mysql://127.0.0.1:4002/hertzbeat?connectionTimeZone=Asia/Shanghai&forceConnectionTimeZoneToSession=true") String url,
+	@DefaultValue("com.mysql.cj.jdbc.Driver") String driverClassName, String username, String password) {
 }


Test patch: