Skip to content

Commit 4326411

Browse files
authored
Merge pull request #13 from essentialkaos/develop
Version 3.0.0
2 parents 36d8cd9 + 1078b9e commit 4326411

7 files changed

+229
-62
lines changed

.codebeatsettings

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"GOLANG": {
3+
"ABC": [15, 25, 50, 70],
4+
"LOC": [30, 45, 70, 100],
5+
"TOO_MANY_IVARS": [12, 16, 20, 24],
6+
"TOO_MANY_FUNCTIONS": [50, 70, 90, 120],
7+
"TOTAL_LOC": [500, 750, 1000, 2000]
8+
}
9+
}

.github/CODE_OF_CONDUCT.md

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Contributor Code of Conduct
2+
3+
As contributors and maintainers of this project, and in the interest of
4+
fostering an open and welcoming community, we pledge to respect all people who
5+
contribute through reporting issues, posting feature requests, updating
6+
documentation, submitting pull requests or patches, and other activities.
7+
8+
We are committed to making participation in this project a harassment-free
9+
experience for everyone, regardless of level of experience, gender, gender
10+
identity and expression, sexual orientation, disability, personal appearance,
11+
body size, race, ethnicity, age, religion, or nationality.
12+
13+
Examples of unacceptable behavior by participants include:
14+
15+
* The use of sexualized language or imagery
16+
* Personal attacks
17+
* Trolling or insulting/derogatory comments
18+
* Public or private harassment
19+
* Publishing other's private information, such as physical or electronic
20+
addresses, without explicit permission
21+
* Other unethical or unprofessional conduct
22+
23+
Project maintainers have the right and responsibility to remove, edit, or
24+
reject comments, commits, code, wiki edits, issues, and other contributions
25+
that are not aligned to this Code of Conduct, or to ban temporarily or
26+
permanently any contributor for other behaviors that they deem inappropriate,
27+
threatening, offensive, or harmful.
28+
29+
By adopting this Code of Conduct, project maintainers commit themselves to
30+
fairly and consistently applying these principles to every aspect of managing
31+
this project. Project maintainers who do not follow or enforce the Code of
32+
Conduct may be permanently removed from the project team.
33+
34+
This Code of Conduct applies both within project spaces and in public spaces
35+
when an individual is representing the project or its community.
36+
37+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
38+
reported by contacting a project maintainer at [INSERT EMAIL ADDRESS]. All
39+
complaints will be reviewed and investigated and will result in a response that
40+
is deemed necessary and appropriate to the circumstances. Maintainers are
41+
obligated to maintain confidentiality with regard to the reporter of an
42+
incident.

.github/CONTRIBUTING.md

+19-21
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
1-
# Contributing Guidelines
2-
3-
Contributing guidelines for open-source EK projects.
4-
5-
**IMPORTANT! Contribute your code only if you have an excellent understanding of project idea and all existing code base. Otherwise, a nicely formatted issue will be more helpful to us.**
6-
7-
### Issues
8-
9-
1. Provide product version where the problem was found;
10-
2. Provide info about your environment;
11-
3. Provide detailed info about your problem;
12-
4. Provide steps to reproduce the problem;
13-
5. Provide actual and expected results.
14-
15-
### Code
16-
17-
1. Check your code **before** creating pull request;
18-
2. If tests are present in a project, add tests for your code;
19-
3. Add inline documentation for your code;
20-
4. Apply code style used throughout the project;
21-
5. Create your pull request to `develop` branch (_pull requests to other branches are not allowed_).
1+
# Contributing Guidelines
2+
3+
**IMPORTANT! Contribute your code only if you have an excellent understanding of project idea and all existing code base. Otherwise, a nicely formatted issue will be more helpful to us.**
4+
5+
### Issues
6+
7+
1. Provide product version where the problem was found;
8+
2. Provide info about your environment;
9+
3. Provide detailed info about your problem;
10+
4. Provide steps to reproduce the problem;
11+
5. Provide actual and expected results.
12+
13+
### Code
14+
15+
1. Check your code **before** creating pull request;
16+
2. If tests are present in a project, add tests for your code;
17+
3. Add inline documentation for your code;
18+
4. Apply code style used throughout the project;
19+
5. Create your pull request to `develop` branch (_pull requests to other branches are not allowed_).

Makefile

+5-6
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
########################################################################################
1+
################################################################################
22

3-
# This Makefile generated by GoMakeGen 0.6.0 using next command:
3+
# This Makefile generated by GoMakeGen 0.6.1 using next command:
44
# gomakegen .
55

6-
########################################################################################
6+
################################################################################
77

88
.PHONY = fmt all clean deps
99

10-
########################################################################################
10+
################################################################################
1111

1212
all: redis-latency-monitor
1313

@@ -16,7 +16,6 @@ redis-latency-monitor:
1616

1717
deps:
1818
git config --global http.https://pkg.re.followRedirects true
19-
go get -d -v github.com/montanaflynn/stats
2019
go get -d -v pkg.re/essentialkaos/ek.v9
2120

2221
fmt:
@@ -25,4 +24,4 @@ fmt:
2524
clean:
2625
rm -f redis-latency-monitor
2726

28-
########################################################################################
27+
################################################################################

common/redis-latency-monitor.spec

+9-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
Summary: Tiny Redis client for latency measurement
1212
Name: redis-latency-monitor
13-
Version: 2.4.0
13+
Version: 3.0.0
1414
Release: 0%{?dist}
1515
Group: Applications/System
1616
License: EKOL
@@ -58,6 +58,14 @@ rm -rf %{buildroot}
5858
###############################################################################
5959

6060
%changelog
61+
* Tue Dec 19 2017 Anton Novojilov <[email protected]> - 3.0.0-0
62+
- Fixed bug with percentile calculation
63+
- ek package updated to latest version
64+
- More precise latency calculation
65+
- Removed external packages
66+
- Improved UI
67+
- Code refactoring
68+
6169
* Tue Oct 03 2017 Anton Novojilov <[email protected]> - 2.4.0-0
6270
- Added option -T/--timestamps for output time as unix timestamp
6371

redis-latency-monitor.go

+46-34
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111
"bufio"
1212
"fmt"
1313
"io"
14-
"math"
1514
"net"
1615
"os"
1716
"runtime"
@@ -22,26 +21,30 @@ import (
2221
"pkg.re/essentialkaos/ek.v9/fmtutil"
2322
"pkg.re/essentialkaos/ek.v9/fmtutil/table"
2423
"pkg.re/essentialkaos/ek.v9/log"
24+
"pkg.re/essentialkaos/ek.v9/mathutil"
2525
"pkg.re/essentialkaos/ek.v9/options"
2626
"pkg.re/essentialkaos/ek.v9/timeutil"
2727
"pkg.re/essentialkaos/ek.v9/usage"
2828

29-
"github.com/montanaflynn/stats"
29+
"github.com/essentialkaos/redis-latency-monitor/stats"
3030
)
3131

3232
// ////////////////////////////////////////////////////////////////////////////////// //
3333

34+
// App info
3435
const (
3536
APP = "Redis Latency Monitor"
36-
VER = "2.4.0"
37+
VER = "3.0.0"
3738
DESC = "Tiny Redis client for latency measurement"
3839
)
3940

41+
// Main constatnts
4042
const (
4143
LATENCY_SAMPLE_RATE int = 10
4244
CONNECT_SAMPLE_RATE = 100
4345
)
4446

47+
// Options
4548
const (
4649
OPT_HOST = "h:host"
4750
OPT_PORT = "p:port"
@@ -196,7 +199,7 @@ func connectToRedis(reconnect bool) error {
196199
// measureLatency measure latency
197200
func measureLatency(interval time.Duration, prettyOutput bool) {
198201
var (
199-
measurements []float64
202+
measurements stats.Data
200203
count, pointer int
201204
t *table.Table
202205
sampleRate int
@@ -232,7 +235,7 @@ func measureLatency(interval time.Duration, prettyOutput bool) {
232235
errors += execCommand(buf)
233236
}
234237

235-
dur := float64(time.Since(start)) / float64(time.Millisecond)
238+
dur := uint64(time.Since(start) / time.Microsecond)
236239
measurements[pointer] = dur
237240

238241
if time.Since(last) >= interval {
@@ -319,42 +322,43 @@ func makeConnection() int {
319322
}
320323

321324
// printMeasurements calculate and print measurements
322-
func printMeasurements(t *table.Table, errors int, measurements []float64, prettyOutput bool) {
323-
min, _ := stats.Min(measurements)
324-
max, _ := stats.Max(measurements)
325-
men, _ := stats.Mean(measurements)
326-
med, _ := stats.Median(measurements)
327-
mgh, _ := stats.Midhinge(measurements)
328-
sdv, _ := stats.StandardDeviation(measurements)
329-
p95, _ := stats.Percentile(measurements, 95.0)
330-
p99, _ := stats.Percentile(measurements, 99.0)
325+
func printMeasurements(t *table.Table, errors int, measurements stats.Data, prettyOutput bool) {
326+
measurements.Sort()
327+
328+
min := stats.Min(measurements)
329+
max := stats.Max(measurements)
330+
men := stats.Mean(measurements)
331+
sdv := stats.StandardDeviation(measurements)
332+
p95 := stats.Percentile(measurements, 95.0)
333+
p99 := stats.Percentile(measurements, 99.0)
331334

332335
if prettyOutput {
333336
t.Print(
334337
timeutil.Format(time.Now(), "%H:%M:%S.%K"),
335338
fmtutil.PrettyNum(len(measurements)),
336339
fmtutil.PrettyNum(errors),
337340
formatNumber(min), formatNumber(max),
338-
formatNumber(men), formatNumber(med),
339-
formatNumber(mgh), formatNumber(sdv),
341+
formatNumber(men), formatNumber(sdv),
340342
formatNumber(p95), formatNumber(p99),
341343
)
342344
} else {
343345
if options.GetB(OPT_TIMESTAMPS) {
344346
outputWriter.WriteString(
345347
fmt.Sprintf(
346-
"%d;%d;%d;%.03f;%.03f;%.03f;%.03f;%.03f;%.03f;%.03f;%.03f;\n",
348+
"%d;%d;%d;%.03f;%.03f;%.03f;%.03f;%.03f;%.03f;\n",
347349
time.Now().Unix(), len(measurements), errors,
348-
min, max, men, med, mgh, sdv, p95, p99,
350+
usToMs(min), usToMs(max), usToMs(men),
351+
usToMs(sdv), usToMs(p95), usToMs(p99),
349352
),
350353
)
351354
} else {
352355
outputWriter.WriteString(
353356
fmt.Sprintf(
354-
"%s;%d;%d;%.03f;%.03f;%.03f;%.03f;%.03f;%.03f;%.03f;%.03f;\n",
357+
"%s;%d;%d;%.03f;%.03f;%.03f;%.03f;%.03f;%.03f;\n",
355358
timeutil.Format(time.Now(), "%Y/%m/%d %H:%M:%S.%K"),
356359
len(measurements), errors,
357-
min, max, men, med, mgh, sdv, p95, p99,
360+
usToMs(min), usToMs(max), usToMs(men),
361+
usToMs(sdv), usToMs(p95), usToMs(p99),
358362
),
359363
)
360364
}
@@ -363,35 +367,43 @@ func printMeasurements(t *table.Table, errors int, measurements []float64, prett
363367
}
364368

365369
// formatNumber format floating number
366-
func formatNumber(value float64) string {
367-
if math.IsNaN(value) {
368-
return "------"
370+
func formatNumber(value uint64) string {
371+
if value == 0 {
372+
return "{s-}------{!}"
369373
}
370374

371-
if value == 0.0 {
372-
return "0{s-}.001{!}"
373-
}
375+
fv := float64(value) / 1000.0
374376

375-
if value > 1000.0 {
376-
value = math.Floor(value)
377+
switch {
378+
case fv > 1000.0:
379+
fv = mathutil.Round(fv, 0)
380+
case fv > 10:
381+
fv = mathutil.Round(fv, 1)
382+
case fv > 1:
383+
fv = mathutil.Round(fv, 2)
377384
}
378385

379-
return strings.Replace(fmtutil.PrettyNum(value), ".", "{s-}.", -1) + "{!}"
386+
return strings.Replace(fmtutil.PrettyNum(fv), ".", "{s-}.", -1) + "{!}"
387+
}
388+
389+
// usToMs convert us in uint64 to ms in float64
390+
func usToMs(us uint64) float64 {
391+
return float64(us) / 1000.0
380392
}
381393

382394
// createOutputTable create and configure output table struct
383395
func createOutputTable() *table.Table {
384396
t := table.NewTable(
385-
"TIME", "SAMPLES", "ERRORS", "MIN", "MAX", "MEAN",
386-
"MEDIAN", "STDDEV", "PERC 95", "PERC 99",
397+
"TIME", "SAMPLES", "ERRORS", "MIN", "MAX",
398+
"MEAN", "STDDEV", "PERC 95", "PERC 99",
387399
)
388400

389401
t.SetSizes(12, 8, 8, 8, 10, 8, 8, 8)
390402

391403
t.SetAlignments(
392404
table.ALIGN_RIGHT, table.ALIGN_RIGHT, table.ALIGN_RIGHT,
393405
table.ALIGN_RIGHT, table.ALIGN_RIGHT, table.ALIGN_RIGHT,
394-
table.ALIGN_RIGHT, table.ALIGN_RIGHT,
406+
table.ALIGN_RIGHT,
395407
)
396408

397409
return t
@@ -419,9 +431,9 @@ func alignTime() time.Time {
419431
}
420432

421433
// createMeasurementsSlice create float64 slice for measurements
422-
func createMeasurementsSlice(sampleRate int) []float64 {
434+
func createMeasurementsSlice(sampleRate int) []uint64 {
423435
size := (options.GetI(OPT_INTERVAL) * 1000) / sampleRate
424-
return make([]float64, size)
436+
return make(stats.Data, size)
425437
}
426438

427439
// flushOutput is function for flushing output

0 commit comments

Comments
 (0)