Commit 52d23ac224f43323e60e4cd2a87cf74597e5e3ba
Merge branch 'master' of github.com:thingsboard/thingsboard
Showing
5 changed files
with
110 additions
and
29 deletions
... | ... | @@ -273,7 +273,8 @@ sql: |
273 | 273 | # Specify whether to remove null characters from strValue of attributes and timeseries before insert |
274 | 274 | remove_null_chars: "${SQL_REMOVE_NULL_CHARS:true}" |
275 | 275 | # Specify whether to log database queries and their parameters generated by entity query repository |
276 | - log_entity_queries: "${SQL_LOG_ENTITY_QUERIES:false}" | |
276 | + log_queries: "${SQL_LOG_QUERIES:false}" | |
277 | + log_queries_threshold: "${SQL_LOG_QUERIES_THRESHOLD:5000}" | |
277 | 278 | postgres: |
278 | 279 | # Specify partitioning size for timestamp key-value storage. Example: DAYS, MONTHS, YEARS, INDEFINITE. |
279 | 280 | ts_key_value_partitioning: "${SQL_POSTGRES_TS_KV_PARTITIONING:MONTHS}" | ... | ... |
... | ... | @@ -43,6 +43,7 @@ import org.thingsboard.server.dao.model.ModelConstants; |
43 | 43 | import java.util.ArrayList; |
44 | 44 | import java.util.Arrays; |
45 | 45 | import java.util.Collection; |
46 | +import java.util.Collections; | |
46 | 47 | import java.util.HashMap; |
47 | 48 | import java.util.HashSet; |
48 | 49 | import java.util.List; |
... | ... | @@ -114,12 +115,12 @@ public class DefaultAlarmQueryRepository implements AlarmQueryRepository { |
114 | 115 | protected final NamedParameterJdbcTemplate jdbcTemplate; |
115 | 116 | private final TransactionTemplate transactionTemplate; |
116 | 117 | |
117 | - @Value("${sql.log_entity_queries:false}") | |
118 | - private boolean logSqlQueries; | |
118 | + private final DefaultQueryLogComponent queryLog; | |
119 | 119 | |
120 | - public DefaultAlarmQueryRepository(NamedParameterJdbcTemplate jdbcTemplate, TransactionTemplate transactionTemplate) { | |
120 | + public DefaultAlarmQueryRepository(NamedParameterJdbcTemplate jdbcTemplate, TransactionTemplate transactionTemplate, DefaultQueryLogComponent queryLog) { | |
121 | 121 | this.jdbcTemplate = jdbcTemplate; |
122 | 122 | this.transactionTemplate = transactionTemplate; |
123 | + this.queryLog = queryLog; | |
123 | 124 | } |
124 | 125 | |
125 | 126 | @Override |
... | ... | @@ -230,8 +231,17 @@ public class DefaultAlarmQueryRepository implements AlarmQueryRepository { |
230 | 231 | if (!textSearchQuery.isEmpty()) { |
231 | 232 | mainQuery = String.format("select * from (%s) a WHERE %s", mainQuery, textSearchQuery); |
232 | 233 | } |
233 | - String countQuery = mainQuery; | |
234 | - int totalElements = jdbcTemplate.queryForObject(String.format("select count(*) from (%s) result", countQuery), ctx, Integer.class); | |
234 | + String countQuery = String.format("select count(*) from (%s) result", mainQuery); | |
235 | + long queryTs = System.currentTimeMillis(); | |
236 | + int totalElements; | |
237 | + try { | |
238 | + totalElements = jdbcTemplate.queryForObject(countQuery, ctx, Integer.class); | |
239 | + } finally { | |
240 | + queryLog.logQuery(ctx, countQuery, System.currentTimeMillis() - queryTs); | |
241 | + } | |
242 | + if (totalElements == 0) { | |
243 | + return AlarmDataAdapter.createAlarmData(pageLink, Collections.emptyList(), totalElements, orderedEntityIds); | |
244 | + } | |
235 | 245 | |
236 | 246 | String dataQuery = mainQuery + sortPart; |
237 | 247 | |
... | ... | @@ -239,10 +249,12 @@ public class DefaultAlarmQueryRepository implements AlarmQueryRepository { |
239 | 249 | if (pageLink.getPageSize() > 0) { |
240 | 250 | dataQuery = String.format("%s limit %s offset %s", dataQuery, pageLink.getPageSize(), startIndex); |
241 | 251 | } |
242 | - List<Map<String, Object>> rows = jdbcTemplate.queryForList(dataQuery, ctx); | |
243 | - if (logSqlQueries) { | |
244 | - log.info("QUERY: {}", dataQuery); | |
245 | - Arrays.asList(ctx.getParameterNames()).forEach(param -> log.info("QUERY PARAM: {}->{}", param, ctx.getValue(param))); | |
252 | + queryTs = System.currentTimeMillis(); | |
253 | + List<Map<String, Object>> rows; | |
254 | + try { | |
255 | + rows = jdbcTemplate.queryForList(dataQuery, ctx); | |
256 | + } finally { | |
257 | + queryLog.logQuery(ctx, dataQuery, System.currentTimeMillis() - queryTs); | |
246 | 258 | } |
247 | 259 | return AlarmDataAdapter.createAlarmData(pageLink, rows, totalElements, orderedEntityIds); |
248 | 260 | }); | ... | ... |
... | ... | @@ -17,12 +17,8 @@ package org.thingsboard.server.dao.sql.query; |
17 | 17 | |
18 | 18 | import lombok.extern.slf4j.Slf4j; |
19 | 19 | import org.apache.commons.lang3.StringUtils; |
20 | -import org.springframework.beans.factory.annotation.Autowired; | |
21 | -import org.springframework.beans.factory.annotation.Value; | |
22 | 20 | import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; |
23 | 21 | import org.springframework.stereotype.Repository; |
24 | -import org.springframework.transaction.TransactionStatus; | |
25 | -import org.springframework.transaction.support.TransactionCallback; | |
26 | 22 | import org.springframework.transaction.support.TransactionTemplate; |
27 | 23 | import org.thingsboard.server.common.data.EntityType; |
28 | 24 | import org.thingsboard.server.common.data.id.CustomerId; |
... | ... | @@ -237,13 +233,12 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { |
237 | 233 | |
238 | 234 | private final NamedParameterJdbcTemplate jdbcTemplate; |
239 | 235 | private final TransactionTemplate transactionTemplate; |
236 | + private final DefaultQueryLogComponent queryLog; | |
240 | 237 | |
241 | - @Value("${sql.log_entity_queries:false}") | |
242 | - private boolean logSqlQueries; | |
243 | - | |
244 | - public DefaultEntityQueryRepository(NamedParameterJdbcTemplate jdbcTemplate, TransactionTemplate transactionTemplate) { | |
238 | + public DefaultEntityQueryRepository(NamedParameterJdbcTemplate jdbcTemplate, TransactionTemplate transactionTemplate, DefaultQueryLogComponent queryLog) { | |
245 | 239 | this.jdbcTemplate = jdbcTemplate; |
246 | 240 | this.transactionTemplate = transactionTemplate; |
241 | + this.queryLog = queryLog; | |
247 | 242 | } |
248 | 243 | |
249 | 244 | @Override |
... | ... | @@ -254,11 +249,14 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { |
254 | 249 | ctx.append(addEntityTableQuery(ctx, query.getEntityFilter())); |
255 | 250 | ctx.append(" e where "); |
256 | 251 | ctx.append(buildEntityWhere(ctx, query.getEntityFilter(), Collections.emptyList())); |
257 | - if (logSqlQueries) { | |
258 | - log.info("QUERY: {}", ctx.getQuery()); | |
259 | - Arrays.asList(ctx.getParameterNames()).forEach(param -> log.info("QUERY PARAM: {}->{}", param, ctx.getValue(param))); | |
260 | - } | |
261 | - return transactionTemplate.execute(status -> jdbcTemplate.queryForObject(ctx.getQuery(), ctx, Long.class)); | |
252 | + return transactionTemplate.execute(status -> { | |
253 | + long startTs = System.currentTimeMillis(); | |
254 | + try { | |
255 | + return jdbcTemplate.queryForObject(ctx.getQuery(), ctx, Long.class); | |
256 | + } finally { | |
257 | + queryLog.logQuery(ctx, ctx.getQuery(), System.currentTimeMillis() - startTs); | |
258 | + } | |
259 | + }); | |
262 | 260 | } |
263 | 261 | |
264 | 262 | @Override |
... | ... | @@ -329,7 +327,14 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { |
329 | 327 | fromClauseCount = fromClauseData; |
330 | 328 | } |
331 | 329 | String countQuery = String.format("select count(id) %s", fromClauseCount); |
332 | - int totalElements = jdbcTemplate.queryForObject(countQuery, ctx, Integer.class); | |
330 | + | |
331 | + long startTs = System.currentTimeMillis(); | |
332 | + int totalElements; | |
333 | + try { | |
334 | + totalElements = jdbcTemplate.queryForObject(countQuery, ctx, Integer.class); | |
335 | + } finally { | |
336 | + queryLog.logQuery(ctx, countQuery, System.currentTimeMillis() - startTs); | |
337 | + } | |
333 | 338 | |
334 | 339 | if (totalElements == 0) { |
335 | 340 | return new PageData<>(); |
... | ... | @@ -354,11 +359,13 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { |
354 | 359 | if (pageLink.getPageSize() > 0) { |
355 | 360 | dataQuery = String.format("%s limit %s offset %s", dataQuery, pageLink.getPageSize(), startIndex); |
356 | 361 | } |
357 | - if (logSqlQueries) { | |
358 | - log.info("QUERY: {}", dataQuery); | |
359 | - Arrays.asList(ctx.getParameterNames()).forEach(param -> log.info("QUERY PARAM: {}->{}", param, ctx.getValue(param))); | |
362 | + startTs = System.currentTimeMillis(); | |
363 | + List<Map<String, Object>> rows; | |
364 | + try { | |
365 | + rows = jdbcTemplate.queryForList(dataQuery, ctx); | |
366 | + } finally { | |
367 | + queryLog.logQuery(ctx, countQuery, System.currentTimeMillis() - startTs); | |
360 | 368 | } |
361 | - List<Map<String, Object>> rows = jdbcTemplate.queryForList(dataQuery, ctx); | |
362 | 369 | return EntityDataAdapter.createEntityData(pageLink, selectionMapping, rows, totalElements); |
363 | 370 | }); |
364 | 371 | } |
... | ... | @@ -486,7 +493,7 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { |
486 | 493 | + SELECT_TYPE + ", " + SELECT_NAME + ", " + SELECT_LABEL + ", " + |
487 | 494 | SELECT_FIRST_NAME + ", " + SELECT_LAST_NAME + ", " + SELECT_EMAIL + ", " + SELECT_REGION + ", " + |
488 | 495 | SELECT_TITLE + ", " + SELECT_COUNTRY + ", " + SELECT_STATE + ", " + SELECT_CITY + ", " + |
489 | - SELECT_ADDRESS + ", " + SELECT_ADDRESS_2 + ", " + SELECT_ZIP + ", " + SELECT_PHONE + ", " + SELECT_ADDITIONAL_INFO + | |
496 | + SELECT_ADDRESS + ", " + SELECT_ADDRESS_2 + ", " + SELECT_ZIP + ", " + SELECT_PHONE + ", " + SELECT_ADDITIONAL_INFO + | |
490 | 497 | ", entity.entity_type as entity_type"; |
491 | 498 | String from = getQueryTemplate(entityFilter.getDirection()); |
492 | 499 | ctx.addUuidParameter("relation_root_id", rootId.getId()); | ... | ... |
1 | +/** | |
2 | + * Copyright © 2016-2020 The Thingsboard Authors | |
3 | + * | |
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | + * you may not use this file except in compliance with the License. | |
6 | + * You may obtain a copy of the License at | |
7 | + * | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | + * | |
10 | + * Unless required by applicable law or agreed to in writing, software | |
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | + * See the License for the specific language governing permissions and | |
14 | + * limitations under the License. | |
15 | + */ | |
16 | +package org.thingsboard.server.dao.sql.query; | |
17 | + | |
18 | +import lombok.extern.slf4j.Slf4j; | |
19 | +import org.springframework.beans.factory.annotation.Value; | |
20 | +import org.springframework.stereotype.Component; | |
21 | + | |
22 | +import java.util.Arrays; | |
23 | + | |
24 | +@Component | |
25 | +@Slf4j | |
26 | +public class DefaultQueryLogComponent implements QueryLogComponent { | |
27 | + | |
28 | + @Value("${sql.log_queries:false}") | |
29 | + private boolean logSqlQueries; | |
30 | + @Value("${sql.log_queries_threshold:5000}") | |
31 | + private long logQueriesThreshold; | |
32 | + | |
33 | + @Override | |
34 | + public void logQuery(QueryContext ctx, String query, long duration) { | |
35 | + if (logSqlQueries && duration > logQueriesThreshold) { | |
36 | + log.info("QUERY: {} took {}ms", query, duration); | |
37 | + Arrays.asList(ctx.getParameterNames()).forEach(param -> log.info("QUERY PARAM: {} -> {}", param, ctx.getValue(param))); | |
38 | + } | |
39 | + } | |
40 | +} | ... | ... |
1 | +/** | |
2 | + * Copyright © 2016-2020 The Thingsboard Authors | |
3 | + * | |
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | + * you may not use this file except in compliance with the License. | |
6 | + * You may obtain a copy of the License at | |
7 | + * | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | + * | |
10 | + * Unless required by applicable law or agreed to in writing, software | |
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | + * See the License for the specific language governing permissions and | |
14 | + * limitations under the License. | |
15 | + */ | |
16 | +package org.thingsboard.server.dao.sql.query; | |
17 | + | |
18 | +public interface QueryLogComponent { | |
19 | + | |
20 | + void logQuery(QueryContext ctx, String query, long duration); | |
21 | +} | ... | ... |