-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdump_command.go
106 lines (85 loc) · 2.38 KB
/
dump_command.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package main
import "C"
import (
"fmt"
"github.com/fluent/fluent-bit-go/output"
"os"
"time"
"unsafe"
)
func Dump(option DumpOption) error {
if option.FileName == "" {
fmt.Println("Filename required")
os.Exit(1)
}
err := Check(CheckOption{FileName: option.FileName})
check(err)
f, err := os.Open(option.FileName)
check(err)
mLength := getMetadataLength(f, option.Verbose)
if mLength > 0 {
readMetadata(f, mLength, option.Verbose)
}
fileSize := fileInfo(f, option.Verbose)
userData := readUserData(f, mLength, fileSize, option.Verbose)
thePointer := unsafe.Pointer(C.CBytes(userData))
decode(thePointer, len(userData))
outputFile, err := os.Create(option.Output)
check(err)
_, err = outputFile.Write(userData)
check(err)
err = outputFile.Close()
check(err)
return nil
}
func decode(data unsafe.Pointer, length int) int {
decoder := output.NewDecoder(data, length)
if decoder == nil {
fmt.Errorf("dec is nil")
}
count := 0
for {
var ts interface{}
var record map[interface{}]interface{}
ret, ts, record := output.GetRecord(decoder)
if ret != 0 { // No more records
break
}
var timestamp time.Time
switch t := ts.(type) {
case output.FLBTime:
timestamp = ts.(output.FLBTime).Time
case uint64:
timestamp = time.Unix(int64(t), 0)
default:
fmt.Println("time provided invalid, defaulting to now.")
timestamp = time.Now()
}
// Print record keys and values
fmt.Printf("[%d] [%s, {", count, timestamp.String())
for k, v := range record {
fmt.Printf("\"%s\": %s, ", k, v)
}
fmt.Printf("}]\n")
count++
}
return 0
}
func readUserData(f *os.File, metadataLength uint16, fileSize int64, verbose bool) []byte {
userDataStart := int64(FileMetaBytesQuantity - MetadataHeader + metadataLength)
remainingBytes := fileSize - userDataStart
f.Seek(userDataStart, 0)
bytesRead, content := readNBytesFromFile(f, remainingBytes)
userData := bytesRead[:content]
if verbose {
fmt.Printf("%d bytes read from User Content: [%s]\n", content, string(userData))
}
return bytesRead
}
func readMetadata(f *os.File, mLength uint16, verbose bool) {
f.Seek(4, 1) //metadata headers
bytesRead, size := readNBytesFromFile(f, int64(mLength-4)) //metadata headers bytes are part of the metadata declared size
if verbose {
fmt.Printf("%d bytes read from Metadata: [%s]\n", size, string(bytesRead[:size]))
}
}