Skip to content

Commit b554195

Browse files
committed
basic logging client
1 parent 63b5a76 commit b554195

File tree

3 files changed

+141
-2
lines changed

3 files changed

+141
-2
lines changed

README.md

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,50 @@
1-
# pipetostackdriverlogs
2-
Simple service that will let you pipe logs directly to stackdriver logging
1+
# LogPipe
2+
Simple service that will let you pipe logs directly to [Stackdriver Logging](https://cloud.google.com/logging/).
3+
4+
## Background
5+
Google App Engine and Container Engine automatically stream logs to Stackdriver Logging. [Docker](https://www.docker.com) also supports [streaming logs to Stackdriver](https://docs.docker.com/engine/admin/logging/gcplogs/).
6+
7+
However, raw Compute Engine does not. Other cloud VMs also do not. You can install the [logging agent](https://cloud.google.com/logging/docs/agent/installation) on Compute Engine, but that requires you to log to a [common log file, custom log file, or syslog](https://cloud.google.com/logging/docs/view/service/agent-logs).
8+
9+
If you want a simple way to stream logs from the Stdout of any program to Stackdriver Logging, this is for you!
10+
11+
# Install
12+
go get -u github.com/thesandlord/logpipe
13+
# Setup
14+
15+
_Note: If you are running on Google Compute Engine, there is no need for any setup._
16+
17+
If you want to use this on your local machine, install the [Google Cloud SDK](cloud.google.com/sdk) and run:
18+
19+
20+
gcloud auth application-default login
21+
22+
If you are running on a VM outside Google Cloud, follow the steps [here](https://developers.google.com/identity/protocols/application-default-credentials#howtheywork) to set the `GOOGLE_APPLICATION_CREDENTIALS` environment variable.
23+
24+
# Usage
25+
26+
```
27+
Usage:
28+
logpipe [OPTIONS]
29+
30+
Application Options:
31+
-p, --project= Google Cloud Platform Project ID
32+
-l, --logname= The name of the log to write to (default: default)
33+
34+
Help Options:
35+
-h, --help Show this help message
36+
```
37+
38+
## Examples
39+
40+
This will log all the output from a Node.js program
41+
42+
node app.js | logpipe -p <YOUR_PROJECT_ID>
43+
44+
This will log the word "hello" 5 times to the "default" log
45+
46+
yes hello | head -n 5 | logpipe -p <YOUR_PROJECT_ID>
47+
48+
This will log the word "test" to the "tester" log
49+
50+
echo test | logpipe -p <YOUR_PROJECT_ID> -l tester

circle.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
deployment:
2+
release:
3+
branch: master
4+
commands:
5+
— go get github.com/mitchellh/gox
6+
— go get github.com/tcnksm/ghr
7+
— gox -ldflags "-X main.Version $BUILD_VERSION -X main.BuildDate $BUILD_DATE" -output "dist/ncd_{{.OS}}_{{.Arch}}"
8+
— ghr -t $GITHUB_TOKEN -u $CIRCLE_PROJECT_USERNAME -r $CIRCLE_PROJECT_REPONAME --replace `git describe --tags` dist/

logpipe.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
Copyright 2017, Google, Inc.
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License.
14+
*/
15+
16+
// Command logpipe is a service that will let you pipe logs directly to Stackdriver Logging.
17+
package main
18+
19+
import (
20+
"bufio"
21+
"fmt"
22+
"log"
23+
"os"
24+
25+
flags "github.com/jessevdk/go-flags"
26+
27+
"cloud.google.com/go/logging"
28+
"golang.org/x/net/context"
29+
)
30+
31+
func main() {
32+
ctx := context.Background()
33+
34+
var opts struct {
35+
ProjectID string `short:"p" long:"project" description:"Google Cloud Platform Project ID" required:"true"`
36+
LogName string `short:"l" long:"logname" description:"The name of the log to write to" default:"default"`
37+
}
38+
39+
flags.Parse(&opts)
40+
41+
projectID := &opts.ProjectID
42+
logName := &opts.LogName
43+
44+
if *projectID == "" {
45+
fmt.Printf("Please specify a project ID\n")
46+
return
47+
}
48+
49+
// Check if Standard In is coming from a pipe
50+
fi, err := os.Stdin.Stat()
51+
if err != nil {
52+
panic(err)
53+
}
54+
if fi.Mode()&os.ModeNamedPipe == 0 {
55+
fmt.Printf("Nothing is piped in so there is nothing to log!\n")
56+
return
57+
}
58+
59+
// Creates a client.
60+
client, err := logging.NewClient(ctx, *projectID)
61+
if err != nil {
62+
log.Fatalf("Failed to create client: %v", err)
63+
}
64+
65+
// Selects the log to write to.
66+
logger := client.Logger(*logName)
67+
68+
// Read from Stdin and log it to Stdout and Stackdriver
69+
scanner := bufio.NewScanner(os.Stdin)
70+
for scanner.Scan() {
71+
text := scanner.Text()
72+
fmt.Println(text)
73+
logger.Log(logging.Entry{Payload: text})
74+
}
75+
76+
// Closes the client and flushes the buffer to the Stackdriver Logging
77+
// service.
78+
if err := client.Close(); err != nil {
79+
log.Fatalf("Failed to close client: %v", err)
80+
}
81+
82+
fmt.Printf("Finished logging\n")
83+
}

0 commit comments

Comments
 (0)