目前我正在寻找Tinkoff 的 JDBC 插件中的 Gattle,当我启用
TRACE
日志时,响应时间会更高,即从 1500 毫秒到 25 秒。
这是我的加特林
logback.xml
设置:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%-5level] %logger{15} - %msg%n%rEx</pattern>
</encoder>
<immediateFlush>false</immediateFlush>
</appender>
<!-- uncomment and set to DEBUG to log all failing HTTP requests -->
<!-- uncomment and set to TRACE to log all HTTP requests -->
<logger name="io.gatling.http.engine.response" level="TRACE" />
<!-- uncomment to log WebSocket events -->
<!-- <logger name="io.gatling.http.action.ws.fsm" level="TRACE" /> -->
<!-- uncomment to log SSE events -->
<!-- <logger name="io.gatling.http.action.sse.fsm" level="TRACE" /> -->
<!-- <root level="TRACE"> -->
<root level="TRACE">
<appender-ref ref="CONSOLE" />
</root>
</configuration>
用于连接定义
object Actions_test {
// database connection
val database_URL: JdbcProtocolBuilder = DB
.url("mariadb")
.username("user")
.password("pw@2024")
.maximumPoolSize(10)
.connectionTimeout(10.second)
// large query
def callingJDBC(): QueryActionBuilder =
jdbc("simple Call")
.query("""your-large-query-here
""".stripMargin)
.check(simpleCheck(x => x.length > 2000)
)
}
适用场景:
class DebugTest extends Simulation {
val scn = scenario("test")
.exec(Actions_test.callingJDBC())
.exitHere
setUp(
scn.inject(
rampUsers(1000).during(500)
),
)
.protocols(Actions_test.database_URL)
.maxDuration(10.minute)
}
如何正确配置此插件的日志记录?请帮助我。
将日志级别设置为跟踪不是您经常要做的事情,除非您确实需要查看正在执行的程序的大量详细信息。将应用程序的根记录器级别设置为
TRACE
并不是一个好主意,因为您将看到来自许多组件(http 客户端、db 客户端、gatting、akka 等)的内容。更好的方法可能是将根记录器级别设置为 WARN
或 INFO
并将某些特定记录器设置为 TRACE
。正如 gatting logback 虚拟配置中所解释的那样
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%-5level] %logger{15} - %msg%n%rEx</pattern>
</encoder>
<immediateFlush>false</immediateFlush>
</appender>
<!-- uncomment and set to DEBUG to log all failing HTTP requests -->
<!-- uncomment and set to TRACE to log all HTTP requests -->
<!--<logger name="io.gatling.http.engine.response" level="TRACE" />-->
<!-- uncomment to log WebSocket events -->
<!--<logger name="io.gatling.http.action.ws.fsm" level="DEBUG" />-->
<!-- uncomment to log SSE events -->
<!--<logger name="io.gatling.http.action.sse.fsm" level="DEBUG" />-->
<root level="WARN">
<appender-ref ref="CONSOLE" />
</root>
</configuration>
不确定您的确切目标是什么,或者为什么您想在
TRACE
水平上取得良好的表现。 Logback 有附加程序,在本例中您使用的是 ConsoleAppender。
顾名思义,
附加在控制台上,或者更准确地说附加在 System.out 或 System.err 上,前者是默认目标。 System.out 和 System.err 都是ConsoleAppender
类型。因此,它们被包装在一个缓冲 I/O 操作的java.io.PrintStream
中。OutputStreamWriter
这意味着每次记录消息时记录器都会执行一次 I/O 操作。您可以将属性 immediateFlush 设置为
false
(默认为 true)来缓冲消息。这个来自OutputStreamAppender
物业名称 类型 描述 immediateFlush
boolean
的默认值为immediateFlush
。立即刷新输出流可确保日志记录事件立即写出,并且在应用程序在未正确关闭附加程序的情况下退出时不会丢失。另一方面,将此属性设置为“false”可能会使记录吞吐量增加四倍(您的里程可能会有所不同)。同样,如果立即刷新设置为“假”并且应用程序退出时附加程序未正确关闭,则尚未写入磁盘的日志记录事件可能会丢失。'true'
当您从日志级别
INFO
更改为 TRACE
时,您将增加记录器必须写入的消息量。所以,看到性能下降是可以接受的。
从 Apache commons loggins 库,您可以阅读以下日志级别消息的最佳实践
消息优先级/级别
确保日志消息的内容和严重性适当非常重要。建议遵循以下准则:
- fatal - 导致提前终止的严重错误。预计这些将立即在状态控制台上可见。
- error - 其他运行时错误或意外情况。预计这些将立即在状态控制台上可见。
- 警告 - 使用已弃用的 API、API 使用不当、“几乎”错误、其他不希望或意外的运行时情况,但不一定是“错误”。预计这些将立即在状态控制台上可见。
- info - 有趣的运行时事件(启动/关闭)。预计这些会立即在控制台上可见,因此要保守并保持在最低限度。
- debug - 有关系统流程的详细信息。希望这些仅写入日志。
- trace - 更详细的信息。希望这些仅写入日志。
话虽这么说,如果您确实需要将日志级别设置为
TRACE
,您可以尝试使用logback的配置并使用不同的appenders,而不是使用gadling提供的默认配置。
我使用以下文件在本地重新创建了您在问题中详细说明的案例
build.sbt
ThisBuild / scalaVersion := "2.13.11"
lazy val GatlingSettings = inConfig(Gatling)(Defaults.testSettings)
lazy val root = (project in file("."))
.enablePlugins(GatlingPlugin)
.settings(
name := "stackoverflow-pocs-secondary",
libraryDependencies ++= Seq(
"ch.qos.logback" % "logback-classic" % "1.4.14",
"com.typesafe.scala-logging" %% "scala-logging" % "3.9.5",
"io.gatling.highcharts" % "gatling-charts-highcharts" % "3.10.3",
"io.gatling" % "gatling-test-framework" % "3.10.3",
"ru.tinkoff" %% "gatling-jdbc-plugin" % "0.10.3",
"org.postgresql" % "postgresql" % "42.7.1"
),
GatlingSettings,
run / fork := true
)
project/plugins.sbt
addSbtPlugin("io.gatling" % "gatling-sbt" % "4.7.0")
src/gatling/BasicSimulation.scala
import io.gatling.core.Predef._
import ru.tinkoff.load.jdbc.Predef._
import ru.tinkoff.load.jdbc.actions.actions._
import ru.tinkoff.load.jdbc.protocol.JdbcProtocolBuilder
import scala.concurrent.duration.DurationInt
class BasicSimulation extends Simulation {
val scn = scenario("test")
.exec(ActionsTest.callingJDBC())
.exitHere
setUp(scn.inject(rampUsers(800).during(30)))
.protocols(ActionsTest.database_URL)
.maxDuration(10.minute)
}
object ActionsTest {
val database_URL: JdbcProtocolBuilder = DB
.url("jdbc:postgresql://localhost:5432/postgres")
.username("admin")
.password("admin")
.maximumPoolSize(10)
.connectionTimeout(10.second)
def callingJDBC(): QueryActionBuilder =
jdbc("simple Call")
.query("select * from dummy_random_data")
.check(simpleCheck(x => x.length > 2000))
}
src/gatling/resources/logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%-5level] %logger{15} - %msg%n%rEx</pattern>
</encoder>
<immediateFlush>false</immediateFlush>
</appender>
<appender name="ASYNC-CONSOLE" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="CONSOLE"/>
<queueSize>16384</queueSize>
<maxFlushTime>MAX_FLUSH_TIME</maxFlushTime>
<neverBlock>false</neverBlock>
</appender>
<root level="WARN">
<appender-ref ref="CONSOLE"/>
<!-- <appender-ref ref="ASYNC-CONSOLE"/> -->
</root>
</configuration>
docker-compose.yaml
version: '3.1'
services:
db:
image: postgres:15.4-alpine3.18
restart: always
environment:
- POSTGRES_PASSWORD=admin
- POSTGRES_USER=admin
- POSTGRES_DB=postgres
ports:
- "5432:5432"
然后我们需要运行以下命令来首先启动数据库,创建表并用一些数据填充它
# start the database
docker compose up -d
# create the table
docker exec -it stackoverflow-pocs-secondary-db-1 psql postgresql://admin:admin@localhost:5432/postgres -c 'create table dummy_random_data ( ─╯
id serial not null,
dummy_string text not null
) ;'
# fill with dummy data
docker exec -it stackoverflow-pocs-secondary-db-1 psql postgresql://admin:admin@localhost:5432/postgres -c 'insert into dummy_random_data(dummy_string) select md5(i::text) from generate_series(1, 100000) s(i);'
最后我们可以运行加特林模拟
sbt Gatling/test
您可以使用不同的 logback 配置多次运行加特林模拟。您应该能够看到每次将根日志级别设置为
TRACE
都会对性能产生一些影响