From daf67b844a712867a07bd3d6d7c31d66b21aa8ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ferdinand=20M=C3=BCtsch?= Date: Sat, 13 Feb 2021 11:23:58 +0100 Subject: [PATCH] refctor: change active users query --- config/config.go | 1 + coverage/coverage.out | 623 ++++++++++++++++++----------------- middlewares/authenticate.go | 2 +- mocks/heartbeat_service.go | 5 + models/user.go | 5 + repositories/heartbeart.go | 72 ++-- repositories/repositories.go | 8 +- repositories/user.go | 31 ++ routes/api/metrics.go | 31 +- services/heartbeat.go | 4 + services/services.go | 3 +- services/user.go | 3 +- 12 files changed, 430 insertions(+), 358 deletions(-) diff --git a/config/config.go b/config/config.go index fcfe882..f3ce24d 100644 --- a/config/config.go +++ b/config/config.go @@ -34,6 +34,7 @@ const ( SimpleDateFormat = "2006-01-02" SimpleDateTimeFormat = "2006-01-02 15:04:05" + ErrUnauthorized = "401 unauthorized" ErrInternalServerError = "500 internal server error" ) diff --git a/coverage/coverage.out b/coverage/coverage.out index f4060a9..68aaf68 100644 --- a/coverage/coverage.out +++ b/coverage/coverage.out @@ -1,22 +1,4 @@ mode: set -github.com/muety/wakapi/models/filters.go:16.56,17.16 1 0 -github.com/muety/wakapi/models/filters.go:29.2,29.19 1 0 -github.com/muety/wakapi/models/filters.go:18.22,19.32 1 0 -github.com/muety/wakapi/models/filters.go:20.17,21.27 1 0 -github.com/muety/wakapi/models/filters.go:22.23,23.33 1 0 -github.com/muety/wakapi/models/filters.go:24.21,25.31 1 0 -github.com/muety/wakapi/models/filters.go:26.22,27.32 1 0 -github.com/muety/wakapi/models/filters.go:32.47,33.21 1 1 -github.com/muety/wakapi/models/filters.go:44.2,44.21 1 1 -github.com/muety/wakapi/models/filters.go:33.21,35.3 1 1 -github.com/muety/wakapi/models/filters.go:35.8,35.23 1 1 -github.com/muety/wakapi/models/filters.go:35.23,37.3 1 0 -github.com/muety/wakapi/models/filters.go:37.8,37.29 1 1 -github.com/muety/wakapi/models/filters.go:37.29,39.3 1 1 -github.com/muety/wakapi/models/filters.go:39.8,39.27 1 1 -github.com/muety/wakapi/models/filters.go:39.27,41.3 1 0 -github.com/muety/wakapi/models/filters.go:41.8,41.28 1 1 -github.com/muety/wakapi/models/filters.go:41.28,43.3 1 0 github.com/muety/wakapi/models/heartbeat.go:32.34,34.2 1 1 github.com/muety/wakapi/models/heartbeat.go:36.65,37.28 1 1 github.com/muety/wakapi/models/heartbeat.go:40.2,41.45 2 1 @@ -38,39 +20,19 @@ github.com/muety/wakapi/models/heartbeat.go:72.37,88.2 1 0 github.com/muety/wakapi/models/heartbeat.go:96.41,98.16 2 0 github.com/muety/wakapi/models/heartbeat.go:101.2,102.10 2 0 github.com/muety/wakapi/models/heartbeat.go:98.16,100.3 1 0 -github.com/muety/wakapi/models/user.go:41.43,44.2 1 0 -github.com/muety/wakapi/models/user.go:46.33,50.2 1 0 -github.com/muety/wakapi/models/user.go:52.45,54.2 1 0 -github.com/muety/wakapi/models/user.go:56.45,58.2 1 0 -github.com/muety/wakapi/models/alias.go:12.32,14.2 1 0 -github.com/muety/wakapi/models/alias.go:16.37,17.35 1 0 -github.com/muety/wakapi/models/alias.go:22.2,22.14 1 0 -github.com/muety/wakapi/models/alias.go:17.35,18.18 1 0 -github.com/muety/wakapi/models/alias.go:18.18,20.4 1 0 -github.com/muety/wakapi/models/interval.go:39.47,40.23 1 0 -github.com/muety/wakapi/models/interval.go:45.2,45.14 1 0 -github.com/muety/wakapi/models/interval.go:40.23,41.13 1 0 -github.com/muety/wakapi/models/interval.go:41.13,43.4 1 0 +github.com/muety/wakapi/models/heartbeats.go:7.31,9.2 1 0 +github.com/muety/wakapi/models/heartbeats.go:11.41,13.2 1 0 +github.com/muety/wakapi/models/heartbeats.go:15.36,17.2 1 0 +github.com/muety/wakapi/models/heartbeats.go:19.43,22.2 2 0 +github.com/muety/wakapi/models/heartbeats.go:24.41,26.18 1 0 +github.com/muety/wakapi/models/heartbeats.go:29.2,29.16 1 0 +github.com/muety/wakapi/models/heartbeats.go:26.18,28.3 1 0 +github.com/muety/wakapi/models/heartbeats.go:32.40,34.18 1 0 +github.com/muety/wakapi/models/heartbeats.go:37.2,37.24 1 0 +github.com/muety/wakapi/models/heartbeats.go:34.18,36.3 1 0 github.com/muety/wakapi/models/language_mapping.go:11.42,13.2 1 0 github.com/muety/wakapi/models/language_mapping.go:15.51,17.2 1 0 github.com/muety/wakapi/models/language_mapping.go:19.52,21.2 1 0 -github.com/muety/wakapi/models/models.go:3.14,5.2 0 1 -github.com/muety/wakapi/models/shared.go:35.52,37.2 1 0 -github.com/muety/wakapi/models/shared.go:39.52,42.16 3 0 -github.com/muety/wakapi/models/shared.go:45.2,47.12 3 0 -github.com/muety/wakapi/models/shared.go:42.16,44.3 1 0 -github.com/muety/wakapi/models/shared.go:51.52,57.22 2 0 -github.com/muety/wakapi/models/shared.go:73.2,76.12 3 0 -github.com/muety/wakapi/models/shared.go:58.14,60.17 2 0 -github.com/muety/wakapi/models/shared.go:63.13,65.8 2 0 -github.com/muety/wakapi/models/shared.go:66.17,68.8 2 0 -github.com/muety/wakapi/models/shared.go:69.10,70.64 1 0 -github.com/muety/wakapi/models/shared.go:60.17,62.4 1 0 -github.com/muety/wakapi/models/shared.go:79.45,81.2 1 0 -github.com/muety/wakapi/models/shared.go:83.51,86.2 2 0 -github.com/muety/wakapi/models/shared.go:88.37,91.2 2 0 -github.com/muety/wakapi/models/shared.go:93.35,95.2 1 0 -github.com/muety/wakapi/models/shared.go:97.34,99.2 1 0 github.com/muety/wakapi/models/summary.go:68.29,70.2 1 1 github.com/muety/wakapi/models/summary.go:72.37,79.2 6 1 github.com/muety/wakapi/models/summary.go:81.35,83.2 1 1 @@ -121,75 +83,215 @@ github.com/muety/wakapi/models/summary.go:211.11,219.6 1 1 github.com/muety/wakapi/models/summary.go:236.33,238.2 1 1 github.com/muety/wakapi/models/summary.go:240.43,242.2 1 1 github.com/muety/wakapi/models/summary.go:244.38,246.2 1 1 -github.com/muety/wakapi/models/heartbeats.go:7.31,9.2 1 0 -github.com/muety/wakapi/models/heartbeats.go:11.41,13.2 1 0 -github.com/muety/wakapi/models/heartbeats.go:15.36,17.2 1 0 -github.com/muety/wakapi/models/heartbeats.go:19.43,22.2 2 0 -github.com/muety/wakapi/models/heartbeats.go:24.41,26.18 1 0 -github.com/muety/wakapi/models/heartbeats.go:29.2,29.16 1 0 -github.com/muety/wakapi/models/heartbeats.go:26.18,28.3 1 0 -github.com/muety/wakapi/models/heartbeats.go:32.40,34.18 1 0 -github.com/muety/wakapi/models/heartbeats.go:37.2,37.24 1 0 -github.com/muety/wakapi/models/heartbeats.go:34.18,36.3 1 0 -github.com/muety/wakapi/config/config.go:102.70,104.2 1 0 -github.com/muety/wakapi/config/config.go:106.65,108.2 1 0 -github.com/muety/wakapi/config/config.go:110.82,120.2 1 0 -github.com/muety/wakapi/config/config.go:122.31,124.2 1 0 -github.com/muety/wakapi/config/config.go:126.32,128.2 1 0 -github.com/muety/wakapi/config/config.go:130.74,131.19 1 0 -github.com/muety/wakapi/config/config.go:132.10,133.34 1 0 -github.com/muety/wakapi/config/config.go:133.34,142.4 8 0 -github.com/muety/wakapi/config/config.go:146.73,147.33 1 0 -github.com/muety/wakapi/config/config.go:147.33,155.17 5 0 -github.com/muety/wakapi/config/config.go:159.3,160.13 2 0 -github.com/muety/wakapi/config/config.go:155.17,157.4 1 0 -github.com/muety/wakapi/config/config.go:164.50,165.19 1 0 -github.com/muety/wakapi/config/config.go:178.2,178.12 1 0 -github.com/muety/wakapi/config/config.go:166.23,170.5 1 0 -github.com/muety/wakapi/config/config.go:171.26,174.5 1 0 -github.com/muety/wakapi/config/config.go:175.24,176.48 1 0 -github.com/muety/wakapi/config/config.go:181.53,191.2 1 1 -github.com/muety/wakapi/config/config.go:193.56,195.16 2 1 -github.com/muety/wakapi/config/config.go:199.2,206.3 1 1 -github.com/muety/wakapi/config/config.go:195.16,197.3 1 0 -github.com/muety/wakapi/config/config.go:209.54,211.2 1 1 -github.com/muety/wakapi/config/config.go:213.60,215.2 1 0 -github.com/muety/wakapi/config/config.go:217.59,219.2 1 0 -github.com/muety/wakapi/config/config.go:221.57,223.2 1 0 -github.com/muety/wakapi/config/config.go:225.53,227.2 1 0 -github.com/muety/wakapi/config/config.go:229.29,231.2 1 1 -github.com/muety/wakapi/config/config.go:233.27,235.16 2 0 -github.com/muety/wakapi/config/config.go:238.2,241.16 3 0 -github.com/muety/wakapi/config/config.go:245.2,245.41 1 0 -github.com/muety/wakapi/config/config.go:235.16,237.3 1 0 -github.com/muety/wakapi/config/config.go:241.16,243.3 1 0 -github.com/muety/wakapi/config/config.go:248.48,260.16 3 0 -github.com/muety/wakapi/config/config.go:263.2,265.16 3 0 -github.com/muety/wakapi/config/config.go:269.2,269.55 1 0 -github.com/muety/wakapi/config/config.go:273.2,273.15 1 0 -github.com/muety/wakapi/config/config.go:260.16,262.3 1 0 -github.com/muety/wakapi/config/config.go:265.16,267.3 1 0 -github.com/muety/wakapi/config/config.go:269.55,271.3 1 0 -github.com/muety/wakapi/config/config.go:276.38,277.43 1 0 -github.com/muety/wakapi/config/config.go:280.2,280.15 1 0 -github.com/muety/wakapi/config/config.go:277.43,279.3 1 0 -github.com/muety/wakapi/config/config.go:283.45,284.27 1 0 -github.com/muety/wakapi/config/config.go:287.2,287.15 1 0 -github.com/muety/wakapi/config/config.go:284.27,286.3 1 0 -github.com/muety/wakapi/config/config.go:290.26,292.2 1 0 -github.com/muety/wakapi/config/config.go:294.20,296.2 1 0 -github.com/muety/wakapi/config/config.go:298.21,303.96 3 0 -github.com/muety/wakapi/config/config.go:307.2,315.52 5 0 -github.com/muety/wakapi/config/config.go:319.2,319.47 1 0 -github.com/muety/wakapi/config/config.go:325.2,325.70 1 0 -github.com/muety/wakapi/config/config.go:329.2,329.28 1 0 -github.com/muety/wakapi/config/config.go:333.2,334.14 2 0 -github.com/muety/wakapi/config/config.go:303.96,305.3 1 0 -github.com/muety/wakapi/config/config.go:315.52,317.3 1 0 -github.com/muety/wakapi/config/config.go:319.47,320.14 1 0 -github.com/muety/wakapi/config/config.go:320.14,322.4 1 0 -github.com/muety/wakapi/config/config.go:325.70,327.3 1 0 -github.com/muety/wakapi/config/config.go:329.28,331.3 1 0 +github.com/muety/wakapi/models/user.go:46.43,49.2 1 0 +github.com/muety/wakapi/models/user.go:51.33,55.2 1 0 +github.com/muety/wakapi/models/user.go:57.45,59.2 1 0 +github.com/muety/wakapi/models/user.go:61.45,63.2 1 0 +github.com/muety/wakapi/models/alias.go:12.32,14.2 1 0 +github.com/muety/wakapi/models/alias.go:16.37,17.35 1 0 +github.com/muety/wakapi/models/alias.go:22.2,22.14 1 0 +github.com/muety/wakapi/models/alias.go:17.35,18.18 1 0 +github.com/muety/wakapi/models/alias.go:18.18,20.4 1 0 +github.com/muety/wakapi/models/filters.go:16.56,17.16 1 0 +github.com/muety/wakapi/models/filters.go:29.2,29.19 1 0 +github.com/muety/wakapi/models/filters.go:18.22,19.32 1 0 +github.com/muety/wakapi/models/filters.go:20.17,21.27 1 0 +github.com/muety/wakapi/models/filters.go:22.23,23.33 1 0 +github.com/muety/wakapi/models/filters.go:24.21,25.31 1 0 +github.com/muety/wakapi/models/filters.go:26.22,27.32 1 0 +github.com/muety/wakapi/models/filters.go:32.47,33.21 1 1 +github.com/muety/wakapi/models/filters.go:44.2,44.21 1 1 +github.com/muety/wakapi/models/filters.go:33.21,35.3 1 1 +github.com/muety/wakapi/models/filters.go:35.8,35.23 1 1 +github.com/muety/wakapi/models/filters.go:35.23,37.3 1 0 +github.com/muety/wakapi/models/filters.go:37.8,37.29 1 1 +github.com/muety/wakapi/models/filters.go:37.29,39.3 1 1 +github.com/muety/wakapi/models/filters.go:39.8,39.27 1 1 +github.com/muety/wakapi/models/filters.go:39.27,41.3 1 0 +github.com/muety/wakapi/models/filters.go:41.8,41.28 1 1 +github.com/muety/wakapi/models/filters.go:41.28,43.3 1 0 +github.com/muety/wakapi/models/interval.go:39.47,40.23 1 0 +github.com/muety/wakapi/models/interval.go:45.2,45.14 1 0 +github.com/muety/wakapi/models/interval.go:40.23,41.13 1 0 +github.com/muety/wakapi/models/interval.go:41.13,43.4 1 0 +github.com/muety/wakapi/models/models.go:3.14,5.2 0 1 +github.com/muety/wakapi/models/shared.go:35.52,37.2 1 0 +github.com/muety/wakapi/models/shared.go:39.52,42.16 3 0 +github.com/muety/wakapi/models/shared.go:45.2,47.12 3 0 +github.com/muety/wakapi/models/shared.go:42.16,44.3 1 0 +github.com/muety/wakapi/models/shared.go:51.52,57.22 2 0 +github.com/muety/wakapi/models/shared.go:73.2,76.12 3 0 +github.com/muety/wakapi/models/shared.go:58.14,60.17 2 0 +github.com/muety/wakapi/models/shared.go:63.13,65.8 2 0 +github.com/muety/wakapi/models/shared.go:66.17,68.8 2 0 +github.com/muety/wakapi/models/shared.go:69.10,70.64 1 0 +github.com/muety/wakapi/models/shared.go:60.17,62.4 1 0 +github.com/muety/wakapi/models/shared.go:79.45,81.2 1 0 +github.com/muety/wakapi/models/shared.go:83.51,86.2 2 0 +github.com/muety/wakapi/models/shared.go:88.37,91.2 2 0 +github.com/muety/wakapi/models/shared.go:93.35,95.2 1 0 +github.com/muety/wakapi/models/shared.go:97.34,99.2 1 0 +github.com/muety/wakapi/utils/color.go:8.90,10.32 2 0 +github.com/muety/wakapi/utils/color.go:15.2,15.15 1 0 +github.com/muety/wakapi/utils/color.go:10.32,11.50 1 0 +github.com/muety/wakapi/utils/color.go:11.50,13.4 1 0 +github.com/muety/wakapi/utils/common.go:10.48,12.2 1 0 +github.com/muety/wakapi/utils/common.go:14.40,16.2 1 0 +github.com/muety/wakapi/utils/common.go:18.45,20.2 1 0 +github.com/muety/wakapi/utils/common.go:22.24,24.2 1 0 +github.com/muety/wakapi/utils/common.go:26.56,29.45 3 1 +github.com/muety/wakapi/utils/common.go:32.2,32.40 1 1 +github.com/muety/wakapi/utils/common.go:29.45,31.3 1 1 +github.com/muety/wakapi/utils/date.go:8.31,10.2 1 0 +github.com/muety/wakapi/utils/date.go:12.43,14.2 1 0 +github.com/muety/wakapi/utils/date.go:16.30,20.2 3 0 +github.com/muety/wakapi/utils/date.go:22.31,25.2 2 0 +github.com/muety/wakapi/utils/date.go:27.30,30.2 2 0 +github.com/muety/wakapi/utils/date.go:32.67,35.33 2 0 +github.com/muety/wakapi/utils/date.go:44.2,44.18 1 0 +github.com/muety/wakapi/utils/date.go:35.33,37.19 2 0 +github.com/muety/wakapi/utils/date.go:40.3,41.10 2 0 +github.com/muety/wakapi/utils/date.go:37.19,39.4 1 0 +github.com/muety/wakapi/utils/date.go:47.50,53.2 5 0 +github.com/muety/wakapi/utils/date.go:56.79,59.36 3 0 +github.com/muety/wakapi/utils/date.go:63.2,63.21 1 0 +github.com/muety/wakapi/utils/date.go:67.2,67.21 1 0 +github.com/muety/wakapi/utils/date.go:71.2,71.13 1 0 +github.com/muety/wakapi/utils/date.go:59.36,62.3 2 0 +github.com/muety/wakapi/utils/date.go:63.21,66.3 2 0 +github.com/muety/wakapi/utils/date.go:67.21,70.3 2 0 +github.com/muety/wakapi/utils/http.go:9.73,12.58 3 0 +github.com/muety/wakapi/utils/http.go:12.58,14.3 1 0 +github.com/muety/wakapi/utils/template.go:8.41,10.16 2 0 +github.com/muety/wakapi/utils/template.go:13.2,13.23 1 0 +github.com/muety/wakapi/utils/template.go:10.16,12.3 1 0 +github.com/muety/wakapi/utils/template.go:16.37,17.30 1 0 +github.com/muety/wakapi/utils/template.go:20.2,20.10 1 0 +github.com/muety/wakapi/utils/template.go:17.30,19.3 1 0 +github.com/muety/wakapi/utils/auth.go:16.79,18.54 2 0 +github.com/muety/wakapi/utils/auth.go:22.2,24.16 3 0 +github.com/muety/wakapi/utils/auth.go:28.2,30.45 3 0 +github.com/muety/wakapi/utils/auth.go:33.2,34.32 2 0 +github.com/muety/wakapi/utils/auth.go:18.54,20.3 1 0 +github.com/muety/wakapi/utils/auth.go:24.16,26.3 1 0 +github.com/muety/wakapi/utils/auth.go:30.45,32.3 1 0 +github.com/muety/wakapi/utils/auth.go:37.65,39.85 2 0 +github.com/muety/wakapi/utils/auth.go:43.2,44.30 2 0 +github.com/muety/wakapi/utils/auth.go:39.85,41.3 1 0 +github.com/muety/wakapi/utils/auth.go:47.94,49.16 2 0 +github.com/muety/wakapi/utils/auth.go:53.2,53.107 1 0 +github.com/muety/wakapi/utils/auth.go:57.2,57.22 1 0 +github.com/muety/wakapi/utils/auth.go:49.16,51.3 1 0 +github.com/muety/wakapi/utils/auth.go:53.107,55.3 1 0 +github.com/muety/wakapi/utils/auth.go:60.56,64.2 3 0 +github.com/muety/wakapi/utils/auth.go:66.55,69.16 3 0 +github.com/muety/wakapi/utils/auth.go:72.2,72.16 1 0 +github.com/muety/wakapi/utils/auth.go:69.16,71.3 1 0 +github.com/muety/wakapi/utils/filesystem.go:14.68,16.16 2 0 +github.com/muety/wakapi/utils/filesystem.go:20.2,21.15 2 0 +github.com/muety/wakapi/utils/filesystem.go:33.2,33.15 1 0 +github.com/muety/wakapi/utils/filesystem.go:16.16,18.3 1 0 +github.com/muety/wakapi/utils/filesystem.go:21.15,23.47 2 0 +github.com/muety/wakapi/utils/filesystem.go:23.47,25.23 2 0 +github.com/muety/wakapi/utils/filesystem.go:29.4,29.19 1 0 +github.com/muety/wakapi/utils/filesystem.go:25.23,27.5 1 0 +github.com/muety/wakapi/utils/strings.go:8.34,10.2 1 0 +github.com/muety/wakapi/utils/strings.go:12.77,13.29 1 0 +github.com/muety/wakapi/utils/strings.go:18.2,18.19 1 0 +github.com/muety/wakapi/utils/strings.go:13.29,14.18 1 0 +github.com/muety/wakapi/utils/strings.go:14.18,16.4 1 0 +github.com/muety/wakapi/utils/summary.go:10.66,11.40 1 0 +github.com/muety/wakapi/utils/summary.go:16.2,16.48 1 0 +github.com/muety/wakapi/utils/summary.go:11.40,12.27 1 0 +github.com/muety/wakapi/utils/summary.go:12.27,14.4 1 0 +github.com/muety/wakapi/utils/summary.go:19.67,22.2 2 0 +github.com/muety/wakapi/utils/summary.go:24.74,26.16 2 0 +github.com/muety/wakapi/utils/summary.go:29.2,29.32 1 0 +github.com/muety/wakapi/utils/summary.go:26.16,28.3 1 0 +github.com/muety/wakapi/utils/summary.go:32.84,35.18 2 0 +github.com/muety/wakapi/utils/summary.go:70.2,70.22 1 0 +github.com/muety/wakapi/utils/summary.go:36.28,37.24 1 0 +github.com/muety/wakapi/utils/summary.go:38.32,40.22 2 0 +github.com/muety/wakapi/utils/summary.go:41.31,42.23 1 0 +github.com/muety/wakapi/utils/summary.go:43.31,45.21 2 0 +github.com/muety/wakapi/utils/summary.go:46.32,47.24 1 0 +github.com/muety/wakapi/utils/summary.go:48.32,50.22 2 0 +github.com/muety/wakapi/utils/summary.go:51.31,52.23 1 0 +github.com/muety/wakapi/utils/summary.go:53.32,54.42 1 0 +github.com/muety/wakapi/utils/summary.go:55.41,57.40 2 0 +github.com/muety/wakapi/utils/summary.go:58.33,59.43 1 0 +github.com/muety/wakapi/utils/summary.go:60.33,61.43 1 0 +github.com/muety/wakapi/utils/summary.go:62.35,63.43 1 0 +github.com/muety/wakapi/utils/summary.go:64.26,65.21 1 0 +github.com/muety/wakapi/utils/summary.go:66.10,67.39 1 0 +github.com/muety/wakapi/utils/summary.go:73.73,80.56 5 0 +github.com/muety/wakapi/utils/summary.go:96.2,103.8 2 0 +github.com/muety/wakapi/utils/summary.go:80.56,82.3 1 0 +github.com/muety/wakapi/utils/summary.go:82.8,82.54 1 0 +github.com/muety/wakapi/utils/summary.go:82.54,84.3 1 0 +github.com/muety/wakapi/utils/summary.go:84.8,86.17 2 0 +github.com/muety/wakapi/utils/summary.go:90.3,91.17 2 0 +github.com/muety/wakapi/utils/summary.go:86.17,88.4 1 0 +github.com/muety/wakapi/utils/summary.go:91.17,93.4 1 0 +github.com/muety/wakapi/config/config.go:103.70,105.2 1 0 +github.com/muety/wakapi/config/config.go:107.65,109.2 1 0 +github.com/muety/wakapi/config/config.go:111.82,121.2 1 0 +github.com/muety/wakapi/config/config.go:123.31,125.2 1 0 +github.com/muety/wakapi/config/config.go:127.32,129.2 1 0 +github.com/muety/wakapi/config/config.go:131.74,132.19 1 0 +github.com/muety/wakapi/config/config.go:133.10,134.34 1 0 +github.com/muety/wakapi/config/config.go:134.34,143.4 8 0 +github.com/muety/wakapi/config/config.go:147.73,148.33 1 0 +github.com/muety/wakapi/config/config.go:148.33,156.17 5 0 +github.com/muety/wakapi/config/config.go:160.3,161.13 2 0 +github.com/muety/wakapi/config/config.go:156.17,158.4 1 0 +github.com/muety/wakapi/config/config.go:165.50,166.19 1 0 +github.com/muety/wakapi/config/config.go:179.2,179.12 1 0 +github.com/muety/wakapi/config/config.go:167.23,171.5 1 0 +github.com/muety/wakapi/config/config.go:172.26,175.5 1 0 +github.com/muety/wakapi/config/config.go:176.24,177.48 1 0 +github.com/muety/wakapi/config/config.go:182.53,192.2 1 1 +github.com/muety/wakapi/config/config.go:194.56,196.16 2 1 +github.com/muety/wakapi/config/config.go:200.2,207.3 1 1 +github.com/muety/wakapi/config/config.go:196.16,198.3 1 0 +github.com/muety/wakapi/config/config.go:210.54,212.2 1 1 +github.com/muety/wakapi/config/config.go:214.60,216.2 1 0 +github.com/muety/wakapi/config/config.go:218.59,220.2 1 0 +github.com/muety/wakapi/config/config.go:222.57,224.2 1 0 +github.com/muety/wakapi/config/config.go:226.53,228.2 1 0 +github.com/muety/wakapi/config/config.go:230.29,232.2 1 1 +github.com/muety/wakapi/config/config.go:234.27,236.16 2 0 +github.com/muety/wakapi/config/config.go:239.2,242.16 3 0 +github.com/muety/wakapi/config/config.go:246.2,246.41 1 0 +github.com/muety/wakapi/config/config.go:236.16,238.3 1 0 +github.com/muety/wakapi/config/config.go:242.16,244.3 1 0 +github.com/muety/wakapi/config/config.go:249.48,261.16 3 0 +github.com/muety/wakapi/config/config.go:264.2,266.16 3 0 +github.com/muety/wakapi/config/config.go:270.2,270.55 1 0 +github.com/muety/wakapi/config/config.go:274.2,274.15 1 0 +github.com/muety/wakapi/config/config.go:261.16,263.3 1 0 +github.com/muety/wakapi/config/config.go:266.16,268.3 1 0 +github.com/muety/wakapi/config/config.go:270.55,272.3 1 0 +github.com/muety/wakapi/config/config.go:277.38,278.43 1 0 +github.com/muety/wakapi/config/config.go:281.2,281.15 1 0 +github.com/muety/wakapi/config/config.go:278.43,280.3 1 0 +github.com/muety/wakapi/config/config.go:284.45,285.27 1 0 +github.com/muety/wakapi/config/config.go:288.2,288.15 1 0 +github.com/muety/wakapi/config/config.go:285.27,287.3 1 0 +github.com/muety/wakapi/config/config.go:291.26,293.2 1 0 +github.com/muety/wakapi/config/config.go:295.20,297.2 1 0 +github.com/muety/wakapi/config/config.go:299.21,304.96 3 0 +github.com/muety/wakapi/config/config.go:308.2,316.52 5 0 +github.com/muety/wakapi/config/config.go:320.2,320.47 1 0 +github.com/muety/wakapi/config/config.go:326.2,326.70 1 0 +github.com/muety/wakapi/config/config.go:330.2,330.28 1 0 +github.com/muety/wakapi/config/config.go:334.2,335.14 2 0 +github.com/muety/wakapi/config/config.go:304.96,306.3 1 0 +github.com/muety/wakapi/config/config.go:316.52,318.3 1 0 +github.com/muety/wakapi/config/config.go:320.47,321.14 1 0 +github.com/muety/wakapi/config/config.go:321.14,323.4 1 0 +github.com/muety/wakapi/config/config.go:326.70,328.3 1 0 +github.com/muety/wakapi/config/config.go:330.28,332.3 1 0 github.com/muety/wakapi/config/utils.go:5.78,7.22 2 0 github.com/muety/wakapi/config/utils.go:13.2,13.11 1 0 github.com/muety/wakapi/config/utils.go:7.22,8.18 1 0 @@ -254,135 +356,30 @@ github.com/muety/wakapi/middlewares/logging.go:134.36,136.2 1 0 github.com/muety/wakapi/middlewares/logging.go:137.42,139.2 1 0 github.com/muety/wakapi/middlewares/logging.go:140.40,142.2 1 0 github.com/muety/wakapi/middlewares/logging.go:143.52,145.2 1 0 -github.com/muety/wakapi/utils/auth.go:16.79,18.54 2 0 -github.com/muety/wakapi/utils/auth.go:22.2,24.16 3 0 -github.com/muety/wakapi/utils/auth.go:28.2,30.45 3 0 -github.com/muety/wakapi/utils/auth.go:33.2,34.32 2 0 -github.com/muety/wakapi/utils/auth.go:18.54,20.3 1 0 -github.com/muety/wakapi/utils/auth.go:24.16,26.3 1 0 -github.com/muety/wakapi/utils/auth.go:30.45,32.3 1 0 -github.com/muety/wakapi/utils/auth.go:37.65,39.85 2 0 -github.com/muety/wakapi/utils/auth.go:43.2,44.30 2 0 -github.com/muety/wakapi/utils/auth.go:39.85,41.3 1 0 -github.com/muety/wakapi/utils/auth.go:47.94,49.16 2 0 -github.com/muety/wakapi/utils/auth.go:53.2,53.107 1 0 -github.com/muety/wakapi/utils/auth.go:57.2,57.22 1 0 -github.com/muety/wakapi/utils/auth.go:49.16,51.3 1 0 -github.com/muety/wakapi/utils/auth.go:53.107,55.3 1 0 -github.com/muety/wakapi/utils/auth.go:60.56,64.2 3 0 -github.com/muety/wakapi/utils/auth.go:66.55,69.16 3 0 -github.com/muety/wakapi/utils/auth.go:72.2,72.16 1 0 -github.com/muety/wakapi/utils/auth.go:69.16,71.3 1 0 -github.com/muety/wakapi/utils/color.go:8.90,10.32 2 0 -github.com/muety/wakapi/utils/color.go:15.2,15.15 1 0 -github.com/muety/wakapi/utils/color.go:10.32,11.50 1 0 -github.com/muety/wakapi/utils/color.go:11.50,13.4 1 0 -github.com/muety/wakapi/utils/date.go:8.31,10.2 1 0 -github.com/muety/wakapi/utils/date.go:12.43,14.2 1 0 -github.com/muety/wakapi/utils/date.go:16.30,20.2 3 0 -github.com/muety/wakapi/utils/date.go:22.31,25.2 2 0 -github.com/muety/wakapi/utils/date.go:27.30,30.2 2 0 -github.com/muety/wakapi/utils/date.go:32.67,35.33 2 0 -github.com/muety/wakapi/utils/date.go:44.2,44.18 1 0 -github.com/muety/wakapi/utils/date.go:35.33,37.19 2 0 -github.com/muety/wakapi/utils/date.go:40.3,41.10 2 0 -github.com/muety/wakapi/utils/date.go:37.19,39.4 1 0 -github.com/muety/wakapi/utils/date.go:47.50,53.2 5 0 -github.com/muety/wakapi/utils/date.go:56.79,59.36 3 0 -github.com/muety/wakapi/utils/date.go:63.2,63.21 1 0 -github.com/muety/wakapi/utils/date.go:67.2,67.21 1 0 -github.com/muety/wakapi/utils/date.go:71.2,71.13 1 0 -github.com/muety/wakapi/utils/date.go:59.36,62.3 2 0 -github.com/muety/wakapi/utils/date.go:63.21,66.3 2 0 -github.com/muety/wakapi/utils/date.go:67.21,70.3 2 0 -github.com/muety/wakapi/utils/strings.go:8.34,10.2 1 0 -github.com/muety/wakapi/utils/strings.go:12.77,13.29 1 0 -github.com/muety/wakapi/utils/strings.go:18.2,18.19 1 0 -github.com/muety/wakapi/utils/strings.go:13.29,14.18 1 0 -github.com/muety/wakapi/utils/strings.go:14.18,16.4 1 0 -github.com/muety/wakapi/utils/template.go:8.41,10.16 2 0 -github.com/muety/wakapi/utils/template.go:13.2,13.23 1 0 -github.com/muety/wakapi/utils/template.go:10.16,12.3 1 0 -github.com/muety/wakapi/utils/template.go:16.37,17.30 1 0 -github.com/muety/wakapi/utils/template.go:20.2,20.10 1 0 -github.com/muety/wakapi/utils/template.go:17.30,19.3 1 0 -github.com/muety/wakapi/utils/common.go:10.48,12.2 1 0 -github.com/muety/wakapi/utils/common.go:14.40,16.2 1 0 -github.com/muety/wakapi/utils/common.go:18.45,20.2 1 0 -github.com/muety/wakapi/utils/common.go:22.24,24.2 1 0 -github.com/muety/wakapi/utils/common.go:26.56,29.45 3 1 -github.com/muety/wakapi/utils/common.go:32.2,32.40 1 1 -github.com/muety/wakapi/utils/common.go:29.45,31.3 1 1 -github.com/muety/wakapi/utils/filesystem.go:14.68,16.16 2 0 -github.com/muety/wakapi/utils/filesystem.go:20.2,21.15 2 0 -github.com/muety/wakapi/utils/filesystem.go:33.2,33.15 1 0 -github.com/muety/wakapi/utils/filesystem.go:16.16,18.3 1 0 -github.com/muety/wakapi/utils/filesystem.go:21.15,23.47 2 0 -github.com/muety/wakapi/utils/filesystem.go:23.47,25.23 2 0 -github.com/muety/wakapi/utils/filesystem.go:29.4,29.19 1 0 -github.com/muety/wakapi/utils/filesystem.go:25.23,27.5 1 0 -github.com/muety/wakapi/utils/http.go:9.73,12.58 3 0 -github.com/muety/wakapi/utils/http.go:12.58,14.3 1 0 -github.com/muety/wakapi/utils/summary.go:10.66,11.40 1 0 -github.com/muety/wakapi/utils/summary.go:16.2,16.48 1 0 -github.com/muety/wakapi/utils/summary.go:11.40,12.27 1 0 -github.com/muety/wakapi/utils/summary.go:12.27,14.4 1 0 -github.com/muety/wakapi/utils/summary.go:19.67,22.2 2 0 -github.com/muety/wakapi/utils/summary.go:24.74,26.16 2 0 -github.com/muety/wakapi/utils/summary.go:29.2,29.32 1 0 -github.com/muety/wakapi/utils/summary.go:26.16,28.3 1 0 -github.com/muety/wakapi/utils/summary.go:32.84,35.18 2 0 -github.com/muety/wakapi/utils/summary.go:70.2,70.22 1 0 -github.com/muety/wakapi/utils/summary.go:36.28,37.24 1 0 -github.com/muety/wakapi/utils/summary.go:38.32,40.22 2 0 -github.com/muety/wakapi/utils/summary.go:41.31,42.23 1 0 -github.com/muety/wakapi/utils/summary.go:43.31,45.21 2 0 -github.com/muety/wakapi/utils/summary.go:46.32,47.24 1 0 -github.com/muety/wakapi/utils/summary.go:48.32,50.22 2 0 -github.com/muety/wakapi/utils/summary.go:51.31,52.23 1 0 -github.com/muety/wakapi/utils/summary.go:53.32,54.42 1 0 -github.com/muety/wakapi/utils/summary.go:55.41,57.40 2 0 -github.com/muety/wakapi/utils/summary.go:58.33,59.43 1 0 -github.com/muety/wakapi/utils/summary.go:60.33,61.43 1 0 -github.com/muety/wakapi/utils/summary.go:62.35,63.43 1 0 -github.com/muety/wakapi/utils/summary.go:64.26,65.21 1 0 -github.com/muety/wakapi/utils/summary.go:66.10,67.39 1 0 -github.com/muety/wakapi/utils/summary.go:73.73,80.56 5 0 -github.com/muety/wakapi/utils/summary.go:96.2,103.8 2 0 -github.com/muety/wakapi/utils/summary.go:80.56,82.3 1 0 -github.com/muety/wakapi/utils/summary.go:82.8,82.54 1 0 -github.com/muety/wakapi/utils/summary.go:82.54,84.3 1 0 -github.com/muety/wakapi/utils/summary.go:84.8,86.17 2 0 -github.com/muety/wakapi/utils/summary.go:90.3,91.17 2 0 -github.com/muety/wakapi/utils/summary.go:86.17,88.4 1 0 -github.com/muety/wakapi/utils/summary.go:91.17,93.4 1 0 -github.com/muety/wakapi/services/user.go:19.73,25.2 1 0 -github.com/muety/wakapi/services/user.go:27.74,28.40 1 0 -github.com/muety/wakapi/services/user.go:32.2,33.16 2 0 -github.com/muety/wakapi/services/user.go:37.2,38.15 2 0 -github.com/muety/wakapi/services/user.go:28.40,30.3 1 0 -github.com/muety/wakapi/services/user.go:33.16,35.3 1 0 -github.com/muety/wakapi/services/user.go:41.72,42.37 1 0 -github.com/muety/wakapi/services/user.go:46.2,47.16 2 0 -github.com/muety/wakapi/services/user.go:51.2,52.15 2 0 -github.com/muety/wakapi/services/user.go:42.37,44.3 1 0 -github.com/muety/wakapi/services/user.go:47.16,49.3 1 0 -github.com/muety/wakapi/services/user.go:55.58,57.2 1 0 -github.com/muety/wakapi/services/user.go:59.61,63.2 2 0 -github.com/muety/wakapi/services/user.go:65.48,67.2 1 0 -github.com/muety/wakapi/services/user.go:69.102,77.93 2 0 -github.com/muety/wakapi/services/user.go:83.2,83.38 1 0 -github.com/muety/wakapi/services/user.go:77.93,79.3 1 0 -github.com/muety/wakapi/services/user.go:79.8,81.3 1 0 -github.com/muety/wakapi/services/user.go:86.73,89.2 2 0 -github.com/muety/wakapi/services/user.go:91.78,95.2 3 0 -github.com/muety/wakapi/services/user.go:97.99,100.2 2 0 -github.com/muety/wakapi/services/user.go:102.106,105.96 3 0 -github.com/muety/wakapi/services/user.go:110.2,110.68 1 0 -github.com/muety/wakapi/services/user.go:105.96,107.3 1 0 -github.com/muety/wakapi/services/user.go:107.8,109.3 1 0 -github.com/muety/wakapi/services/user.go:113.57,116.2 2 0 -github.com/muety/wakapi/services/user.go:118.38,120.2 1 0 +github.com/muety/wakapi/services/heartbeat.go:17.141,23.2 1 0 +github.com/muety/wakapi/services/heartbeat.go:25.72,27.2 1 0 +github.com/muety/wakapi/services/heartbeat.go:29.80,31.2 1 0 +github.com/muety/wakapi/services/heartbeat.go:33.53,35.2 1 0 +github.com/muety/wakapi/services/heartbeat.go:37.76,39.2 1 0 +github.com/muety/wakapi/services/heartbeat.go:41.96,43.2 1 0 +github.com/muety/wakapi/services/heartbeat.go:45.111,47.16 2 0 +github.com/muety/wakapi/services/heartbeat.go:50.2,50.43 1 0 +github.com/muety/wakapi/services/heartbeat.go:47.16,49.3 1 0 +github.com/muety/wakapi/services/heartbeat.go:53.116,55.2 1 0 +github.com/muety/wakapi/services/heartbeat.go:57.78,59.2 1 0 +github.com/muety/wakapi/services/heartbeat.go:61.62,63.2 1 0 +github.com/muety/wakapi/services/heartbeat.go:65.116,67.16 2 0 +github.com/muety/wakapi/services/heartbeat.go:71.2,71.28 1 0 +github.com/muety/wakapi/services/heartbeat.go:75.2,75.24 1 0 +github.com/muety/wakapi/services/heartbeat.go:67.16,69.3 1 0 +github.com/muety/wakapi/services/heartbeat.go:71.28,73.3 1 0 +github.com/muety/wakapi/services/key_value.go:14.89,19.2 1 0 +github.com/muety/wakapi/services/key_value.go:21.83,23.2 1 0 +github.com/muety/wakapi/services/key_value.go:25.78,27.16 2 0 +github.com/muety/wakapi/services/key_value.go:33.2,33.11 1 0 +github.com/muety/wakapi/services/key_value.go:27.16,32.3 1 0 +github.com/muety/wakapi/services/key_value.go:36.72,38.2 1 0 +github.com/muety/wakapi/services/key_value.go:40.60,42.2 1 0 github.com/muety/wakapi/services/aggregation.go:24.142,31.2 1 0 github.com/muety/wakapi/services/aggregation.go:40.43,42.37 1 0 github.com/muety/wakapi/services/aggregation.go:46.2,48.19 3 0 @@ -458,71 +455,6 @@ github.com/muety/wakapi/services/alias.go:95.21,97.4 1 0 github.com/muety/wakapi/services/alias.go:104.31,106.3 1 0 github.com/muety/wakapi/services/alias.go:111.52,112.51 1 0 github.com/muety/wakapi/services/alias.go:112.51,114.3 1 0 -github.com/muety/wakapi/services/key_value.go:14.89,19.2 1 0 -github.com/muety/wakapi/services/key_value.go:21.83,23.2 1 0 -github.com/muety/wakapi/services/key_value.go:25.78,27.16 2 0 -github.com/muety/wakapi/services/key_value.go:33.2,33.11 1 0 -github.com/muety/wakapi/services/key_value.go:27.16,32.3 1 0 -github.com/muety/wakapi/services/key_value.go:36.72,38.2 1 0 -github.com/muety/wakapi/services/key_value.go:40.60,42.2 1 0 -github.com/muety/wakapi/services/language_mapping.go:18.118,24.2 1 0 -github.com/muety/wakapi/services/language_mapping.go:26.86,28.2 1 0 -github.com/muety/wakapi/services/language_mapping.go:30.96,31.53 1 0 -github.com/muety/wakapi/services/language_mapping.go:35.2,36.16 2 0 -github.com/muety/wakapi/services/language_mapping.go:39.2,40.22 2 0 -github.com/muety/wakapi/services/language_mapping.go:31.53,33.3 1 0 -github.com/muety/wakapi/services/language_mapping.go:36.16,38.3 1 0 -github.com/muety/wakapi/services/language_mapping.go:43.92,46.16 3 0 -github.com/muety/wakapi/services/language_mapping.go:50.2,50.33 1 0 -github.com/muety/wakapi/services/language_mapping.go:53.2,53.22 1 0 -github.com/muety/wakapi/services/language_mapping.go:46.16,48.3 1 0 -github.com/muety/wakapi/services/language_mapping.go:50.33,52.3 1 0 -github.com/muety/wakapi/services/language_mapping.go:56.109,58.16 2 0 -github.com/muety/wakapi/services/language_mapping.go:62.2,63.20 2 0 -github.com/muety/wakapi/services/language_mapping.go:58.16,60.3 1 0 -github.com/muety/wakapi/services/language_mapping.go:66.82,67.26 1 0 -github.com/muety/wakapi/services/language_mapping.go:70.2,72.12 3 0 -github.com/muety/wakapi/services/language_mapping.go:67.26,69.3 1 0 -github.com/muety/wakapi/services/language_mapping.go:75.74,78.2 1 0 -github.com/muety/wakapi/services/misc.go:23.126,30.2 1 0 -github.com/muety/wakapi/services/misc.go:42.50,44.48 1 0 -github.com/muety/wakapi/services/misc.go:48.2,50.19 3 0 -github.com/muety/wakapi/services/misc.go:44.48,46.3 1 0 -github.com/muety/wakapi/services/misc.go:53.51,59.40 4 0 -github.com/muety/wakapi/services/misc.go:63.2,66.56 2 0 -github.com/muety/wakapi/services/misc.go:77.2,77.12 1 0 -github.com/muety/wakapi/services/misc.go:59.40,61.3 1 0 -github.com/muety/wakapi/services/misc.go:66.56,67.27 1 0 -github.com/muety/wakapi/services/misc.go:67.27,72.4 1 0 -github.com/muety/wakapi/services/misc.go:73.8,75.3 1 0 -github.com/muety/wakapi/services/misc.go:80.116,81.24 1 0 -github.com/muety/wakapi/services/misc.go:81.24,82.144 1 0 -github.com/muety/wakapi/services/misc.go:91.3,91.48 1 0 -github.com/muety/wakapi/services/misc.go:82.144,84.4 1 0 -github.com/muety/wakapi/services/misc.go:84.9,90.4 2 0 -github.com/muety/wakapi/services/misc.go:91.48,94.4 2 0 -github.com/muety/wakapi/services/misc.go:98.86,101.30 3 0 -github.com/muety/wakapi/services/misc.go:106.2,109.17 1 0 -github.com/muety/wakapi/services/misc.go:113.2,116.17 1 0 -github.com/muety/wakapi/services/misc.go:101.30,104.3 2 0 -github.com/muety/wakapi/services/misc.go:109.17,111.3 1 0 -github.com/muety/wakapi/services/misc.go:116.17,118.3 1 0 -github.com/muety/wakapi/services/heartbeat.go:17.141,23.2 1 0 -github.com/muety/wakapi/services/heartbeat.go:25.72,27.2 1 0 -github.com/muety/wakapi/services/heartbeat.go:29.80,31.2 1 0 -github.com/muety/wakapi/services/heartbeat.go:33.53,35.2 1 0 -github.com/muety/wakapi/services/heartbeat.go:37.76,39.2 1 0 -github.com/muety/wakapi/services/heartbeat.go:41.111,43.16 2 0 -github.com/muety/wakapi/services/heartbeat.go:46.2,46.43 1 0 -github.com/muety/wakapi/services/heartbeat.go:43.16,45.3 1 0 -github.com/muety/wakapi/services/heartbeat.go:49.116,51.2 1 0 -github.com/muety/wakapi/services/heartbeat.go:53.78,55.2 1 0 -github.com/muety/wakapi/services/heartbeat.go:57.62,59.2 1 0 -github.com/muety/wakapi/services/heartbeat.go:61.116,63.16 2 0 -github.com/muety/wakapi/services/heartbeat.go:67.2,67.28 1 0 -github.com/muety/wakapi/services/heartbeat.go:71.2,71.24 1 0 -github.com/muety/wakapi/services/heartbeat.go:63.16,65.3 1 0 -github.com/muety/wakapi/services/heartbeat.go:67.28,69.3 1 0 github.com/muety/wakapi/services/summary.go:27.149,35.2 1 1 github.com/muety/wakapi/services/summary.go:39.120,42.52 2 1 github.com/muety/wakapi/services/summary.go:47.2,47.44 1 1 @@ -612,3 +544,72 @@ github.com/muety/wakapi/services/summary.go:324.54,326.3 1 1 github.com/muety/wakapi/services/summary.go:331.59,333.25 2 1 github.com/muety/wakapi/services/summary.go:336.2,336.32 1 1 github.com/muety/wakapi/services/summary.go:333.25,335.3 1 1 +github.com/muety/wakapi/services/user.go:19.73,25.2 1 0 +github.com/muety/wakapi/services/user.go:27.74,28.40 1 0 +github.com/muety/wakapi/services/user.go:32.2,33.16 2 0 +github.com/muety/wakapi/services/user.go:37.2,38.15 2 0 +github.com/muety/wakapi/services/user.go:28.40,30.3 1 0 +github.com/muety/wakapi/services/user.go:33.16,35.3 1 0 +github.com/muety/wakapi/services/user.go:41.72,42.37 1 0 +github.com/muety/wakapi/services/user.go:46.2,47.16 2 0 +github.com/muety/wakapi/services/user.go:51.2,52.15 2 0 +github.com/muety/wakapi/services/user.go:42.37,44.3 1 0 +github.com/muety/wakapi/services/user.go:47.16,49.3 1 0 +github.com/muety/wakapi/services/user.go:55.58,57.2 1 0 +github.com/muety/wakapi/services/user.go:59.61,62.2 2 0 +github.com/muety/wakapi/services/user.go:64.48,66.2 1 0 +github.com/muety/wakapi/services/user.go:68.102,76.93 2 0 +github.com/muety/wakapi/services/user.go:82.2,82.38 1 0 +github.com/muety/wakapi/services/user.go:76.93,78.3 1 0 +github.com/muety/wakapi/services/user.go:78.8,80.3 1 0 +github.com/muety/wakapi/services/user.go:85.73,88.2 2 0 +github.com/muety/wakapi/services/user.go:90.78,94.2 3 0 +github.com/muety/wakapi/services/user.go:96.99,99.2 2 0 +github.com/muety/wakapi/services/user.go:101.106,104.96 3 0 +github.com/muety/wakapi/services/user.go:109.2,109.68 1 0 +github.com/muety/wakapi/services/user.go:104.96,106.3 1 0 +github.com/muety/wakapi/services/user.go:106.8,108.3 1 0 +github.com/muety/wakapi/services/user.go:112.57,115.2 2 0 +github.com/muety/wakapi/services/user.go:117.38,119.2 1 0 +github.com/muety/wakapi/services/language_mapping.go:18.118,24.2 1 0 +github.com/muety/wakapi/services/language_mapping.go:26.86,28.2 1 0 +github.com/muety/wakapi/services/language_mapping.go:30.96,31.53 1 0 +github.com/muety/wakapi/services/language_mapping.go:35.2,36.16 2 0 +github.com/muety/wakapi/services/language_mapping.go:39.2,40.22 2 0 +github.com/muety/wakapi/services/language_mapping.go:31.53,33.3 1 0 +github.com/muety/wakapi/services/language_mapping.go:36.16,38.3 1 0 +github.com/muety/wakapi/services/language_mapping.go:43.92,46.16 3 0 +github.com/muety/wakapi/services/language_mapping.go:50.2,50.33 1 0 +github.com/muety/wakapi/services/language_mapping.go:53.2,53.22 1 0 +github.com/muety/wakapi/services/language_mapping.go:46.16,48.3 1 0 +github.com/muety/wakapi/services/language_mapping.go:50.33,52.3 1 0 +github.com/muety/wakapi/services/language_mapping.go:56.109,58.16 2 0 +github.com/muety/wakapi/services/language_mapping.go:62.2,63.20 2 0 +github.com/muety/wakapi/services/language_mapping.go:58.16,60.3 1 0 +github.com/muety/wakapi/services/language_mapping.go:66.82,67.26 1 0 +github.com/muety/wakapi/services/language_mapping.go:70.2,72.12 3 0 +github.com/muety/wakapi/services/language_mapping.go:67.26,69.3 1 0 +github.com/muety/wakapi/services/language_mapping.go:75.74,78.2 1 0 +github.com/muety/wakapi/services/misc.go:23.126,30.2 1 0 +github.com/muety/wakapi/services/misc.go:42.50,44.48 1 0 +github.com/muety/wakapi/services/misc.go:48.2,50.19 3 0 +github.com/muety/wakapi/services/misc.go:44.48,46.3 1 0 +github.com/muety/wakapi/services/misc.go:53.51,59.40 4 0 +github.com/muety/wakapi/services/misc.go:63.2,66.56 2 0 +github.com/muety/wakapi/services/misc.go:77.2,77.12 1 0 +github.com/muety/wakapi/services/misc.go:59.40,61.3 1 0 +github.com/muety/wakapi/services/misc.go:66.56,67.27 1 0 +github.com/muety/wakapi/services/misc.go:67.27,72.4 1 0 +github.com/muety/wakapi/services/misc.go:73.8,75.3 1 0 +github.com/muety/wakapi/services/misc.go:80.116,81.24 1 0 +github.com/muety/wakapi/services/misc.go:81.24,82.144 1 0 +github.com/muety/wakapi/services/misc.go:91.3,91.48 1 0 +github.com/muety/wakapi/services/misc.go:82.144,84.4 1 0 +github.com/muety/wakapi/services/misc.go:84.9,90.4 2 0 +github.com/muety/wakapi/services/misc.go:91.48,94.4 2 0 +github.com/muety/wakapi/services/misc.go:98.86,101.30 3 0 +github.com/muety/wakapi/services/misc.go:106.2,109.17 1 0 +github.com/muety/wakapi/services/misc.go:113.2,116.17 1 0 +github.com/muety/wakapi/services/misc.go:101.30,104.3 2 0 +github.com/muety/wakapi/services/misc.go:109.17,111.3 1 0 +github.com/muety/wakapi/services/misc.go:116.17,118.3 1 0 diff --git a/middlewares/authenticate.go b/middlewares/authenticate.go index 8a56475..08a8c9f 100644 --- a/middlewares/authenticate.go +++ b/middlewares/authenticate.go @@ -57,7 +57,7 @@ func (m *AuthenticateMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Reques if m.redirectTarget == "" { w.WriteHeader(http.StatusUnauthorized) - w.Write([]byte("401 unauthorized")) + w.Write([]byte(conf.ErrUnauthorized)) } else { http.SetCookie(w, m.config.GetClearCookie(models.AuthCookieKey, "/")) http.Redirect(w, r, m.redirectTarget, http.StatusFound) diff --git a/mocks/heartbeat_service.go b/mocks/heartbeat_service.go index 68c74bf..282d706 100644 --- a/mocks/heartbeat_service.go +++ b/mocks/heartbeat_service.go @@ -30,6 +30,11 @@ func (m *HeartbeatServiceMock) CountByUser(user *models.User) (int64, error) { return args.Get(0).(int64), args.Error(0) } +func (m *HeartbeatServiceMock) CountByUsers(users []*models.User) ([]*models.CountByUser, error) { + args := m.Called(users) + return args.Get(0).([]*models.CountByUser), args.Error(0) +} + func (m *HeartbeatServiceMock) GetAllWithin(time time.Time, time2 time.Time, user *models.User) ([]*models.Heartbeat, error) { args := m.Called(time, time2, user) return args.Get(0).([]*models.Heartbeat), args.Error(1) diff --git a/models/user.go b/models/user.go index 9494e16..79b6b83 100644 --- a/models/user.go +++ b/models/user.go @@ -38,6 +38,11 @@ type TimeByUser struct { Time CustomTime } +type CountByUser struct { + User string + Count int64 +} + func (c *CredentialsReset) IsValid() bool { return validatePassword(c.PasswordNew) && c.PasswordNew == c.PasswordRepeat diff --git a/repositories/heartbeart.go b/repositories/heartbeart.go index d514fd0..dd37234 100644 --- a/repositories/heartbeart.go +++ b/repositories/heartbeart.go @@ -26,27 +26,6 @@ func (r *HeartbeatRepository) InsertBatch(heartbeats []*models.Heartbeat) error return nil } -func (r *HeartbeatRepository) Count() (int64, error) { - var count int64 - if err := r.db. - Model(&models.Heartbeat{}). - Count(&count).Error; err != nil { - return 0, err - } - return count, nil -} - -func (r *HeartbeatRepository) CountByUser(user *models.User) (int64, error) { - var count int64 - if err := r.db. - Model(&models.Heartbeat{}). - Where(&models.Heartbeat{UserID: user.ID}). - Count(&count).Error; err != nil { - return 0, err - } - return count, nil -} - func (r *HeartbeatRepository) GetLatestByOriginAndUser(origin string, user *models.User) (*models.Heartbeat, error) { var heartbeat models.Heartbeat if err := r.db. @@ -85,6 +64,57 @@ func (r *HeartbeatRepository) GetFirstByUsers() ([]*models.TimeByUser, error) { return result, nil } +func (r *HeartbeatRepository) GetLastByUsers() ([]*models.TimeByUser, error) { + var result []*models.TimeByUser + r.db.Model(&models.User{}). + Select("users.id as user, max(time) as time"). + Joins("left join heartbeats on users.id = heartbeats.user_id"). + Group("user"). + Scan(&result) + return result, nil +} + +func (r *HeartbeatRepository) Count() (int64, error) { + var count int64 + if err := r.db. + Model(&models.Heartbeat{}). + Count(&count).Error; err != nil { + return 0, err + } + return count, nil +} + +func (r *HeartbeatRepository) CountByUser(user *models.User) (int64, error) { + var count int64 + if err := r.db. + Model(&models.Heartbeat{}). + Where(&models.Heartbeat{UserID: user.ID}). + Count(&count).Error; err != nil { + return 0, err + } + return count, nil +} + +func (r *HeartbeatRepository) CountByUsers(users []*models.User) ([]*models.CountByUser, error) { + var counts []*models.CountByUser + + userIds := make([]string, len(users)) + for i, u := range users { + userIds[i] = u.ID + } + + if err := r.db. + Model(&models.User{}). + Select("users.id as user, count(heartbeats.id) as count"). + Joins("left join heartbeats on users.id = heartbeats.user_id"). + Where("user_id in ?", userIds). + Group("user"). + Find(&counts).Error; err != nil { + return counts, err + } + return counts, nil +} + func (r *HeartbeatRepository) DeleteBefore(t time.Time) error { if err := r.db. Where("time <= ?", t). diff --git a/repositories/repositories.go b/repositories/repositories.go index ae8596e..7bceac2 100644 --- a/repositories/repositories.go +++ b/repositories/repositories.go @@ -17,11 +17,13 @@ type IAliasRepository interface { type IHeartbeatRepository interface { InsertBatch([]*models.Heartbeat) error - Count() (int64, error) - CountByUser(*models.User) (int64, error) GetAllWithin(time.Time, time.Time, *models.User) ([]*models.Heartbeat, error) GetFirstByUsers() ([]*models.TimeByUser, error) + GetLastByUsers() ([]*models.TimeByUser, error) GetLatestByOriginAndUser(string, *models.User) (*models.Heartbeat, error) + Count() (int64, error) + CountByUser(*models.User) (int64, error) + CountByUsers([]*models.User) ([]*models.CountByUser, error) DeleteBefore(time.Time) error } @@ -47,9 +49,11 @@ type ISummaryRepository interface { type IUserRepository interface { GetById(string) (*models.User, error) + GetByIds([]string) ([]*models.User, error) GetByApiKey(string) (*models.User, error) GetAll() ([]*models.User, error) GetByLoggedInAfter(time.Time) ([]*models.User, error) + GetByLastActiveAfter(time.Time) ([]*models.User, error) Count() (int64, error) InsertOrGet(*models.User) (*models.User, bool, error) Update(*models.User) (*models.User, error) diff --git a/repositories/user.go b/repositories/user.go index 6f709c8..0fcb048 100644 --- a/repositories/user.go +++ b/repositories/user.go @@ -23,6 +23,17 @@ func (r *UserRepository) GetById(userId string) (*models.User, error) { return u, nil } +func (r *UserRepository) GetByIds(userIds []string) ([]*models.User, error) { + var users []*models.User + if err := r.db. + Model(&models.User{}). + Where("id in ?", userIds). + Find(&users).Error; err != nil { + return nil, err + } + return users, nil +} + func (r *UserRepository) GetByApiKey(key string) (*models.User, error) { u := &models.User{} if err := r.db.Where(&models.User{ApiKey: key}).First(u).Error; err != nil { @@ -51,6 +62,26 @@ func (r *UserRepository) GetByLoggedInAfter(t time.Time) ([]*models.User, error) return users, nil } +// Returns a list of user ids, whose last heartbeat is not older than t +// NOTE: Only ID field will be populated +func (r *UserRepository) GetByLastActiveAfter(t time.Time) ([]*models.User, error) { + subQuery1 := r.db.Model(&models.User{}). + Select("users.id as user, max(time) as time"). + Joins("left join heartbeats on users.id = heartbeats.user_id"). + Group("user") + + var userIds []string + if err := r.db. + Select("user as id"). + Table("(?) as q", subQuery1). + Where("time >= ?", t). + Scan(&userIds).Error; err != nil { + return nil, err + } + + return r.GetByIds(userIds) +} + func (r *UserRepository) Count() (int64, error) { var count int64 if err := r.db. diff --git a/routes/api/metrics.go b/routes/api/metrics.go index 521d72b..c9e64e1 100644 --- a/routes/api/metrics.go +++ b/routes/api/metrics.go @@ -11,7 +11,6 @@ import ( mm "github.com/muety/wakapi/models/metrics" "github.com/muety/wakapi/services" "github.com/muety/wakapi/utils" - "go.uber.org/atomic" "net/http" "sort" "time" @@ -72,6 +71,7 @@ func (h *MetricsHandler) Get(w http.ResponseWriter, r *http.Request) { reqUser := r.Context().Value(models.UserKey).(*models.User) if reqUser == nil { w.WriteHeader(http.StatusUnauthorized) + w.Write([]byte(conf.ErrUnauthorized)) return } @@ -80,6 +80,7 @@ func (h *MetricsHandler) Get(w http.ResponseWriter, r *http.Request) { if userMetrics, err := h.getUserMetrics(reqUser); err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(conf.ErrInternalServerError)) + return } else { for _, m := range *userMetrics { metrics = append(metrics, m) @@ -90,6 +91,7 @@ func (h *MetricsHandler) Get(w http.ResponseWriter, r *http.Request) { if adminMetrics, err := h.getAdminMetrics(reqUser); err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(conf.ErrInternalServerError)) + return } else { for _, m := range *adminMetrics { metrics = append(metrics, m) @@ -249,30 +251,19 @@ func (h *MetricsHandler) getAdminMetrics(user *models.User) (*mm.Metrics, error) }) // Count per-user heartbeats - type userCount struct { - user string - count int64 + + userCounts, err := h.heartbeatSrvc.CountByUsers(activeUsers) + if err != nil { + logbuch.Error("failed to count heartbeats for active users", err.Error()) + return nil, err } - i := atomic.NewUint32(uint32(len(activeUsers))) - c := make(chan *userCount, len(activeUsers)) - - for _, u := range activeUsers { - go func(u *models.User) { - count, _ := h.heartbeatSrvc.CountByUser(u) - c <- &userCount{user: u.ID, count: count} - if i.Dec() == 0 { - close(c) - } - }(u) - } - - for uc := range c { + for _, uc := range userCounts { metrics = append(metrics, &mm.CounterMetric{ Name: MetricsPrefix + "_admin_user_heartbeats_total", Desc: DescAdminUserHeartbeats, - Value: int(uc.count), - Labels: []mm.Label{{Key: "user", Value: uc.user}}, + Value: int(uc.Count), + Labels: []mm.Label{{Key: "user", Value: uc.User}}, }) } diff --git a/services/heartbeat.go b/services/heartbeat.go index c2faeca..faae574 100644 --- a/services/heartbeat.go +++ b/services/heartbeat.go @@ -38,6 +38,10 @@ func (srv *HeartbeatService) CountByUser(user *models.User) (int64, error) { return srv.repository.CountByUser(user) } +func (srv *HeartbeatService) CountByUsers(users []*models.User) ([]*models.CountByUser, error) { + return srv.repository.CountByUsers(users) +} + func (srv *HeartbeatService) GetAllWithin(from, to time.Time, user *models.User) ([]*models.Heartbeat, error) { heartbeats, err := srv.repository.GetAllWithin(from, to, user) if err != nil { diff --git a/services/services.go b/services/services.go index 2138cd1..48dc6ed 100644 --- a/services/services.go +++ b/services/services.go @@ -28,8 +28,9 @@ type IAliasService interface { type IHeartbeatService interface { Insert(*models.Heartbeat) error InsertBatch([]*models.Heartbeat) error - CountByUser(*models.User) (int64, error) Count() (int64, error) + CountByUser(*models.User) (int64, error) + CountByUsers([]*models.User) ([]*models.CountByUser, error) GetAllWithin(time.Time, time.Time, *models.User) ([]*models.Heartbeat, error) GetFirstByUsers() ([]*models.TimeByUser, error) GetLatestByOriginAndUser(string, *models.User) (*models.Heartbeat, error) diff --git a/services/user.go b/services/user.go index d3fd84c..3322137 100644 --- a/services/user.go +++ b/services/user.go @@ -57,9 +57,8 @@ func (srv *UserService) GetAll() ([]*models.User, error) { } func (srv *UserService) GetActive() ([]*models.User, error) { - // a user is considered active if she has logged in to the web interface at least once within the last x days minDate := time.Now().Add(-24 * time.Hour * time.Duration(srv.Config.App.InactiveDays)) - return srv.repository.GetByLoggedInAfter(minDate) + return srv.repository.GetByLastActiveAfter(minDate) } func (srv *UserService) Count() (int64, error) {