/
main.go
139 lines (124 loc) · 4.9 KB
/
main.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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package main
import (
"context"
"crypto/tls"
"log"
"net/http"
"os"
"strconv"
"strings"
"code.cloudfoundry.org/cli/plugin"
"code.cloudfoundry.org/log-cache-cli/v4/internal/command"
"golang.org/x/term"
)
// semver version is set via ldflags at compile time
var version string
type LogCacheCLI struct{}
func (c *LogCacheCLI) Run(conn plugin.CliConnection, args []string) {
isTerminal := term.IsTerminal(int(os.Stdout.Fd()))
skipSSL, err := conn.IsSSLDisabled()
if err != nil {
log.Fatal(err)
}
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{
InsecureSkipVerify: skipSSL, //nolint:gosec
}
l := log.New(os.Stderr, "", 0)
switch args[0] {
case "query":
var opts []command.QueryOption
command.Query(context.Background(), conn, args[1:], http.DefaultClient, l, os.Stdout, opts...)
case "tail":
var opts []command.TailOption
if !isTerminal {
opts = append(opts, command.WithTailNoHeaders())
}
command.Tail(context.Background(), conn, args[1:], http.DefaultClient, l, os.Stdout, opts...)
case "log-meta":
var opts []command.MetaOption
if !isTerminal {
opts = append(opts, command.WithMetaNoHeaders())
}
command.Meta(context.Background(), conn, args[1:], http.DefaultClient, l, os.Stdout, opts...)
}
}
func (c *LogCacheCLI) GetMetadata() plugin.PluginMetadata {
// ignore any errors and use the default plugin.VersionType if version
// cannot be parsed
split := strings.Split(version, ".")
v := plugin.VersionType{}
if len(split) == 3 {
v.Major = readOrZero(split[0])
v.Minor = readOrZero(split[1])
v.Build = readOrZero(split[2])
}
return plugin.PluginMetadata{
Name: "log-cache",
Version: v,
Commands: []plugin.Command{
{
Name: "tail",
HelpText: "Output logs for a source-id/app",
UsageDetails: plugin.Usage{
Usage: `tail [options] <source-id/app>
ENVIRONMENT VARIABLES:
LOG_CACHE_ADDR Overrides the default location of log-cache.
LOG_CACHE_SKIP_AUTH Set to 'true' to disable CF authentication.`,
Options: map[string]string{
"-start-time": "Start of query range in UNIX nanoseconds.",
"-end-time": "End of query range in UNIX nanoseconds.",
"-envelope-type, -t": "Envelope type filter. Available filters: 'log', 'counter', 'gauge', 'timer', 'event', and 'any'.",
"-envelope-class, -c": "Envelope class filter. Available filters: 'logs', 'metrics', and 'any'.",
"-follow, -f": "Output appended to stdout as logs are egressed.",
"-json": "Output envelopes in JSON format.",
"-lines, -n": "Number of envelopes to return. Default is 10.",
"-new-line": "Character used for new line substition, must be single unicode character. Default is '\\n'.",
"-name-filter": "Filters metrics by name.",
},
},
},
{
Name: "log-meta",
HelpText: "Show all available meta information",
UsageDetails: plugin.Usage{
Usage: `log-meta [options]
ENVIRONMENT VARIABLES:
LOG_CACHE_ADDR Overrides the default location of log-cache.
LOG_CACHE_SKIP_AUTH Set to 'true' to disable CF authentication.`,
Options: map[string]string{
"-source-type": "Source type of information to show. Available: 'all', 'application', 'service', 'platform', and 'unknown'. Excludes unknown sources unless 'all' or 'unknown' is selected, or `--guid` is used. To receive information on platform or unknown source id's, you must have the doppler.firehose, or logs.admin scope.",
"-sort-by": "Sort by specified column. Available: 'source-id', 'source', 'source-type', 'count', 'expired', 'cache-duration', and 'rate'.",
"-noise": "Fetch and display the rate of envelopes per minute for the last minute. WARNING: This is slow...",
"-guid": "Display raw source GUIDs with no source Names. Incompatible with 'source' and 'source-type' for --sort-by. Only allows 'platform' for --source-type",
},
},
},
{
Name: "query",
HelpText: "Issues a PromQL query against Log Cache",
UsageDetails: plugin.Usage{
Usage: `query <promql-query> [options]
ENVIRONMENT VARIABLES:
LOG_CACHE_ADDR Overrides the default location of log-cache.
LOG_CACHE_SKIP_AUTH Set to 'true' to disable CF authentication.`,
Options: map[string]string{
"-time": "Effective time for query execution of an instant query. Cannont be used with --start, --end, or --step. Can be a unix timestamp or RFC3339.",
"-start": "Start time for a range query. Cannont be used with --time. Can be a unix timestamp or RFC3339.",
"-end": "End time for a range query. Cannont be used with --time. Can be a unix timestamp or RFC3339.",
"-step": "Step interval for a range query. Cannot be used with --time.",
},
},
},
},
}
}
func readOrZero(s string) int {
n, err := strconv.Atoi(s)
if err != nil {
return 0
}
return n
}
func main() {
plugin.Start(&LogCacheCLI{})
}