Skip to content

Commit b023387

Browse files
authored
Fix build for darwin and windows (#327)
* Fix build for darwin and windows * Remove unexpected dependencies
1 parent 7641923 commit b023387

File tree

4 files changed

+237
-213
lines changed

4 files changed

+237
-213
lines changed

pkg/collect/host_filesystem_performance.go

Lines changed: 0 additions & 213 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,9 @@
11
package collect
22

33
import (
4-
"encoding/json"
5-
"log"
64
"math"
75
"math/rand"
8-
"os"
9-
"path/filepath"
10-
"sort"
11-
"sync"
12-
"syscall"
136
"time"
14-
15-
"github.com/pkg/errors"
16-
"k8s.io/apimachinery/pkg/api/resource"
177
)
188

199
func init() {
@@ -44,209 +34,6 @@ type FSPerfResults struct {
4434
IOPS int
4535
}
4636

47-
type Durations []time.Duration
48-
49-
func (d Durations) Len() int {
50-
return len(d)
51-
}
52-
53-
func (d Durations) Less(i, j int) bool {
54-
return d[i] < d[j]
55-
}
56-
57-
func (d Durations) Swap(i, j int) {
58-
d[i], d[j] = d[j], d[i]
59-
}
60-
61-
func HostFilesystemPerformance(c *HostCollector) (map[string][]byte, error) {
62-
var operationSize uint64 = 1024
63-
if c.Collect.FilesystemPerformance.OperationSizeBytes != 0 {
64-
operationSize = c.Collect.FilesystemPerformance.OperationSizeBytes
65-
}
66-
67-
var fileSize uint64 = 10 * 1024 * 1024
68-
if c.Collect.FilesystemPerformance.FileSize != "" {
69-
quantity, err := resource.ParseQuantity(c.Collect.FilesystemPerformance.FileSize)
70-
if err != nil {
71-
return nil, errors.Wrapf(err, "failed to parse fileSize %q", c.Collect.FilesystemPerformance.FileSize)
72-
}
73-
fileSizeInt64, ok := quantity.AsInt64()
74-
if !ok {
75-
return nil, errors.Wrapf(err, "failed to parse fileSize %q", c.Collect.FilesystemPerformance.FileSize)
76-
}
77-
fileSize = uint64(fileSizeInt64)
78-
}
79-
80-
if c.Collect.FilesystemPerformance.Directory == "" {
81-
return nil, errors.New("Directory is required to collect filesystem performance info")
82-
}
83-
if err := os.MkdirAll(c.Collect.FilesystemPerformance.Directory, 0700); err != nil {
84-
return nil, errors.Wrapf(err, "failed to mkdir %q", c.Collect.FilesystemPerformance.Directory)
85-
}
86-
filename := filepath.Join(c.Collect.FilesystemPerformance.Directory, "fsperf")
87-
88-
f, err := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600)
89-
if err != nil {
90-
return nil, errors.Wrapf(err, "open %s", filename)
91-
}
92-
defer func() {
93-
if err := f.Close(); err != nil {
94-
log.Println(err.Error())
95-
}
96-
if err := os.Remove(filename); err != nil {
97-
log.Println(err.Error())
98-
}
99-
}()
100-
101-
// Sequential writes benchmark
102-
var written uint64 = 0
103-
var results Durations
104-
105-
for {
106-
if written >= fileSize {
107-
break
108-
}
109-
110-
data := make([]byte, int(operationSize))
111-
rand.Read(data)
112-
113-
start := time.Now()
114-
115-
n, err := f.Write(data)
116-
if err != nil {
117-
return nil, errors.Wrapf(err, "write to %s", filename)
118-
}
119-
if c.Collect.FilesystemPerformance.Sync {
120-
if err := f.Sync(); err != nil {
121-
return nil, errors.Wrapf(err, "sync %s", filename)
122-
}
123-
} else if c.Collect.FilesystemPerformance.Datasync {
124-
if err := syscall.Fdatasync(int(f.Fd())); err != nil {
125-
return nil, errors.Wrapf(err, "datasync %s", filename)
126-
}
127-
}
128-
129-
d := time.Now().Sub(start)
130-
results = append(results, d)
131-
132-
written += uint64(n)
133-
}
134-
135-
if len(results) == 0 {
136-
return nil, errors.New("No filesystem performance results collected")
137-
}
138-
139-
sort.Sort(results)
140-
141-
var sum time.Duration
142-
for _, d := range results {
143-
sum += d
144-
}
145-
146-
fsPerf := &FSPerfResults{
147-
Min: results[0],
148-
Max: results[len(results)-1],
149-
Average: sum / time.Duration(len(results)),
150-
P1: results[getPercentileIndex(.01, len(results))],
151-
P5: results[getPercentileIndex(.05, len(results))],
152-
P10: results[getPercentileIndex(.1, len(results))],
153-
P20: results[getPercentileIndex(.2, len(results))],
154-
P30: results[getPercentileIndex(.3, len(results))],
155-
P40: results[getPercentileIndex(.4, len(results))],
156-
P50: results[getPercentileIndex(.5, len(results))],
157-
P60: results[getPercentileIndex(.6, len(results))],
158-
P70: results[getPercentileIndex(.7, len(results))],
159-
P80: results[getPercentileIndex(.8, len(results))],
160-
P90: results[getPercentileIndex(.9, len(results))],
161-
P95: results[getPercentileIndex(.95, len(results))],
162-
P99: results[getPercentileIndex(.99, len(results))],
163-
P995: results[getPercentileIndex(.995, len(results))],
164-
P999: results[getPercentileIndex(.999, len(results))],
165-
P9995: results[getPercentileIndex(.9995, len(results))],
166-
P9999: results[getPercentileIndex(.9999, len(results))],
167-
}
168-
169-
// Random IOPS benchmark
170-
171-
// Re-open the file read+write in direct mode to prevent caching
172-
if err := f.Close(); err != nil {
173-
return nil, errors.Wrapf(err, "close %s", filename)
174-
}
175-
f, err = os.OpenFile(filename, os.O_RDWR|syscall.O_DIRECT, 0600)
176-
if err != nil {
177-
return nil, errors.Wrapf(err, "open direct %s", filename)
178-
}
179-
180-
offsets := make([]int64, len(results))
181-
182-
for index, p := range rand.Perm(len(results)) {
183-
offsets[index] = int64(p) * int64(operationSize)
184-
}
185-
186-
// Use multiple workers to keep the filesystem busy. Since operations are serialized on a single
187-
// file, more than 2 does not improve IOPS.
188-
workers := 2
189-
wg := sync.WaitGroup{}
190-
m := sync.Mutex{}
191-
192-
errs := make(chan error, workers)
193-
194-
start := time.Now()
195-
196-
for i := 0; i < workers; i++ {
197-
wg.Add(1)
198-
199-
go func(i int) {
200-
defer wg.Done()
201-
202-
data := make([]byte, int(operationSize))
203-
fd := int(f.Fd())
204-
205-
for idx, offset := range offsets {
206-
if idx%workers != i {
207-
continue
208-
}
209-
210-
m.Lock()
211-
n, err := syscall.Pread(fd, data, offset)
212-
m.Unlock()
213-
214-
if err != nil {
215-
errs <- errors.Wrapf(err, "failed to pread %d bytes to %s at offset %d", len(data), filename, offset)
216-
}
217-
if n != len(data) {
218-
errs <- errors.Wrapf(err, "pread %d of %d bytes to %s at offset %d", n, len(data), filename, offset)
219-
}
220-
}
221-
}(i)
222-
}
223-
224-
wg.Wait()
225-
if len(errs) > 0 {
226-
return nil, <-errs
227-
}
228-
229-
d := time.Now().Sub(start)
230-
nsPerIO := d / time.Duration(len(offsets))
231-
iops := time.Second / nsPerIO
232-
233-
fsPerf.IOPS = int(iops)
234-
235-
collectorName := c.Collect.FilesystemPerformance.CollectorName
236-
if collectorName == "" {
237-
collectorName = "filesystemPerformance"
238-
}
239-
name := filepath.Join("filesystemPerformance", collectorName+".json")
240-
b, err := json.Marshal(fsPerf)
241-
if err != nil {
242-
return nil, errors.Wrap(err, "failed to marshal fs perf results")
243-
}
244-
245-
return map[string][]byte{
246-
name: b,
247-
}, nil
248-
}
249-
25037
func getPercentileIndex(p float64, items int) int {
25138
if p >= 1 {
25239
return items - 1
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package collect
2+
3+
import "github.com/pkg/errors"
4+
5+
func HostFilesystemPerformance(c *HostCollector) (map[string][]byte, error) {
6+
return nil, errors.New("Filesystem performance collector is only implemented for Linux")
7+
}

0 commit comments

Comments
 (0)