<commit_before>package manta

// A fieldpath, used to walk through the flattened table hierarchy
type fieldpath struct {
	hierarchy []*dt
	index     []int32
	tree      *HuffmanTree
	finished  bool
}

// Typedef for a field operation function
type FieldPathOpFcn func(*reader, *fieldpath)

// Initialize a fieldpath object
func fielpath_init(parentTbl *dt) *fieldpath {
	fp := &fieldpath{
		hierarchy: make([]*dt, 0),
		index:     make([]int32, 0),
	}

	fp.hierarchy = append(fp.hierarchy, parentTbl)
	fp.index = append(fp.index, -1) // Always start at -1
	fp.finished = false

	return fp
}

// Walk an encoded fieldpath based on a huffman tree
func (fp *fieldpath) fieldpath_walk(r *reader) []dt_field {
	fields := make([]dt_field, 0)

	// where is do-while when you need it -.-
	node := (*fp.tree).(HuffmanNode)
	for fp.finished == false {
		if r.readBits(1) == 1 {
			switch i := node.right.(type) {
			case HuffmanLeaf:
				i.value.(FieldPathOpFcn)(r, fp)
				break
			case HuffmanNode:
				node = i
				break
			}
		} else {
			switch i := node.left.(type) {
			case HuffmanLeaf:
				i.value.(FieldPathOpFcn)(r, fp)
				break
			case HuffmanNode:
				node = i
				break
			}
		}
	}

	return fields
}

// Returns a huffman tree based on the operation weights
func fieldpath_huffman() HuffmanTree {
	FieldPathOperations := make(map[int]interface{})

	FieldPathOperations[36271] = PlusOne
	FieldPathOperations[10334] = PlusTwo
	FieldPathOperations[1375] = PlusThree
	FieldPathOperations[646] = PlusFour
	FieldPathOperations[4128] = PlusN
	FieldPathOperations[35] = PushOneLeftDeltaZeroRightZero
	FieldPathOperations[3] = PushOneLeftDeltaZeroRightNonZero
	FieldPathOperations[521] = PushOneLeftDeltaOneRightZero
	FieldPathOperations[2942] = PushOneLeftDeltaOneRightNonZero
	FieldPathOperations[560] = PushOneLeftDeltaNRightZero
	FieldPathOperations[471] = PushOneLeftDeltaNRightNonZero
	FieldPathOperations[10530] = PushOneLeftDeltaNRightNonZeroPack6Bits
	FieldPathOperations[251] = PushOneLeftDeltaNRightNonZeroPack8Bits
	FieldPathOperations[0] = PushTwoLeftDeltaZero
	FieldPathOperations[0] = PushTwoLeftDeltaOne
	FieldPathOperations[0] = PushTwoLeftDeltaN
	FieldPathOperations[0] = PushTwoPack5LeftDeltaZero
	FieldPathOperations[0] = PushTwoPack5LeftDeltaOne
	FieldPathOperations[0] = PushTwoPack5LeftDeltaN
	FieldPathOperations[0] = PushThreeLeftDeltaZero
	FieldPathOperations[0] = PushThreeLeftDeltaOne
	FieldPathOperations[0] = PushThreeLeftDeltaN
	FieldPathOperations[0] = PushThreePack5LeftDeltaZero
	FieldPathOperations[0] = PushThreePack5LeftDeltaOne
	FieldPathOperations[0] = PushThreePack5LeftDeltaN
	FieldPathOperations[0] = PushN
	FieldPathOperations[310] = PushNAndNonTopological
	FieldPathOperations[2] = PopOnePlusOne
	FieldPathOperations[0] = PopOnePlusN
	FieldPathOperations[1837] = PopAllButOnePlusOne
	FieldPathOperations[149] = PopAllButOnePlusN
	FieldPathOperations[300] = PopAllButOnePlusNPack3Bits
	FieldPathOperations[634] = PopAllButOnePlusNPack6Bits
	FieldPathOperations[0] = PopNPlusOne
	FieldPathOperations[0] = PopNPlusN
	FieldPathOperations[1] = PopNAndNonTopographical
	FieldPathOperations[76] = NonTopoComplex
	FieldPathOperations[271] = NonTopoPenultimatePlusOne
	FieldPathOperations[99] = NonTopoComplexPack4Bits
	FieldPathOperations[25474] = FieldPathEncodeFinish

	return buildTree(FieldPathOperations)
}

func PlusOne(r *reader, fp *fieldpath) {
	fp.index[len(fp.index)-1] += 1
}

func PlusTwo(r *reader, fp *fieldpath) {
	fp.index[len(fp.index)-1] += 2
}

func PlusThree(r *reader, fp *fieldpath) {
	fp.index[len(fp.index)-1] += 3
}

func PlusFour(r *reader, fp *fieldpath) {
	fp.index[len(fp.index)-1] += 4
}

func PlusN(r *reader, fp *fieldpath) {

}

func PushOneLeftDeltaZeroRightZero(r *reader, fp *fieldpath) {

}

func PushOneLeftDeltaZeroRightNonZero(r *reader, fp *fieldpath) {

}

func PushOneLeftDeltaOneRightZero(r *reader, fp *fieldpath) {

}

func PushOneLeftDeltaOneRightNonZero(r *reader, fp *fieldpath) {

}

func PushOneLeftDeltaNRightZero(r *reader, fp *fieldpath) {

}

func PushOneLeftDeltaNRightNonZero(r *reader, fp *fieldpath) {

}

func PushOneLeftDeltaNRightNonZeroPack6Bits(r *reader, fp *fieldpath) {

}

func PushOneLeftDeltaNRightNonZeroPack8Bits(r *reader, fp *fieldpath) {

}

func PushTwoLeftDeltaZero(r *reader, fp *fieldpath) {

}

func PushTwoLeftDeltaOne(r *reader, fp *fieldpath) {

}

func PushTwoLeftDeltaN(r *reader, fp *fieldpath) {

}

func PushTwoPack5LeftDeltaZero(r *reader, fp *fieldpath) {

}

func PushTwoPack5LeftDeltaOne(r *reader, fp *fieldpath) {

}

func PushTwoPack5LeftDeltaN(r *reader, fp *fieldpath) {

}

func PushThreeLeftDeltaZero(r *reader, fp *fieldpath) {

}

func PushThreeLeftDeltaOne(r *reader, fp *fieldpath) {

}

func PushThreeLeftDeltaN(r *reader, fp *fieldpath) {

}

func PushThreePack5LeftDeltaZero(r *reader, fp *fieldpath) {

}

func PushThreePack5LeftDeltaOne(r *reader, fp *fieldpath) {

}

func PushThreePack5LeftDeltaN(r *reader, fp *fieldpath) {

}

func PushN(r *reader, fp *fieldpath) {

}

func PushNAndNonTopological(r *reader, fp *fieldpath) {

}

func PopOnePlusOne(r *reader, fp *fieldpath) {

}

func PopOnePlusN(r *reader, fp *fieldpath) {

}

func PopAllButOnePlusOne(r *reader, fp *fieldpath) {

}

func PopAllButOnePlusN(r *reader, fp *fieldpath) {

}

func PopAllButOnePlusNPackN(r *reader, fp *fieldpath) {

}

func PopAllButOnePlusNPack3Bits(r *reader, fp *fieldpath) {

}

func PopAllButOnePlusNPack6Bits(r *reader, fp *fieldpath) {

}

func PopNPlusOne(r *reader, fp *fieldpath) {

}

func PopNPlusN(r *reader, fp *fieldpath) {

}

func PopNAndNonTopographical(r *reader, fp *fieldpath) {

}

func NonTopoComplex(r *reader, fp *fieldpath) {

}

func NonTopoPenultimatePlusOne(r *reader, fp *fieldpath) {

}

func NonTopoComplexPack4Bits(r *reader, fp *fieldpath) {

}

func FieldPathEncodeFinish(r *reader, fp *fieldpath) {
	fp.finished = true
}
<commit_msg>Remove break from fieldpath_walk<commit_after>package manta

// A fieldpath, used to walk through the flattened table hierarchy
type fieldpath struct {
	hierarchy []*dt
	index     []int32
	tree      *HuffmanTree
	finished  bool
}

// Typedef for a field operation function
type FieldPathOpFcn func(*reader, *fieldpath)

// Initialize a fieldpath object
func fielpath_init(parentTbl *dt) *fieldpath {
	fp := &fieldpath{
		hierarchy: make([]*dt, 0),
		index:     make([]int32, 0),
	}

	fp.hierarchy = append(fp.hierarchy, parentTbl)
	fp.index = append(fp.index, -1) // Always start at -1
	fp.finished = false

	return fp
}

// Walk an encoded fieldpath based on a huffman tree
func (fp *fieldpath) fieldpath_walk(r *reader) []dt_field {
	fields := make([]dt_field, 0)

	// where is do-while when you need it -.-
	node := (*fp.tree).(HuffmanNode)
	for fp.finished == false {
		if r.readBits(1) == 1 {
			switch i := node.right.(type) {
			case HuffmanLeaf:
				i.value.(FieldPathOpFcn)(r, fp)
			case HuffmanNode:
				node = i
			}
		} else {
			switch i := node.left.(type) {
			case HuffmanLeaf:
				i.value.(FieldPathOpFcn)(r, fp)
			case HuffmanNode:
				node = i
			}
		}
	}

	return fields
}

// Returns a huffman tree based on the operation weights
func fieldpath_huffman() HuffmanTree {
	FieldPathOperations := make(map[int]interface{})

	FieldPathOperations[36271] = PlusOne
	FieldPathOperations[10334] = PlusTwo
	FieldPathOperations[1375] = PlusThree
	FieldPathOperations[646] = PlusFour
	FieldPathOperations[4128] = PlusN
	FieldPathOperations[35] = PushOneLeftDeltaZeroRightZero
	FieldPathOperations[3] = PushOneLeftDeltaZeroRightNonZero
	FieldPathOperations[521] = PushOneLeftDeltaOneRightZero
	FieldPathOperations[2942] = PushOneLeftDeltaOneRightNonZero
	FieldPathOperations[560] = PushOneLeftDeltaNRightZero
	FieldPathOperations[471] = PushOneLeftDeltaNRightNonZero
	FieldPathOperations[10530] = PushOneLeftDeltaNRightNonZeroPack6Bits
	FieldPathOperations[251] = PushOneLeftDeltaNRightNonZeroPack8Bits
	FieldPathOperations[0] = PushTwoLeftDeltaZero
	FieldPathOperations[0] = PushTwoLeftDeltaOne
	FieldPathOperations[0] = PushTwoLeftDeltaN
	FieldPathOperations[0] = PushTwoPack5LeftDeltaZero
	FieldPathOperations[0] = PushTwoPack5LeftDeltaOne
	FieldPathOperations[0] = PushTwoPack5LeftDeltaN
	FieldPathOperations[0] = PushThreeLeftDeltaZero
	FieldPathOperations[0] = PushThreeLeftDeltaOne
	FieldPathOperations[0] = PushThreeLeftDeltaN
	FieldPathOperations[0] = PushThreePack5LeftDeltaZero
	FieldPathOperations[0] = PushThreePack5LeftDeltaOne
	FieldPathOperations[0] = PushThreePack5LeftDeltaN
	FieldPathOperations[0] = PushN
	FieldPathOperations[310] = PushNAndNonTopological
	FieldPathOperations[2] = PopOnePlusOne
	FieldPathOperations[0] = PopOnePlusN
	FieldPathOperations[1837] = PopAllButOnePlusOne
	FieldPathOperations[149] = PopAllButOnePlusN
	FieldPathOperations[300] = PopAllButOnePlusNPack3Bits
	FieldPathOperations[634] = PopAllButOnePlusNPack6Bits
	FieldPathOperations[0] = PopNPlusOne
	FieldPathOperations[0] = PopNPlusN
	FieldPathOperations[1] = PopNAndNonTopographical
	FieldPathOperations[76] = NonTopoComplex
	FieldPathOperations[271] = NonTopoPenultimatePlusOne
	FieldPathOperations[99] = NonTopoComplexPack4Bits
	FieldPathOperations[25474] = FieldPathEncodeFinish

	return buildTree(FieldPathOperations)
}

func PlusOne(r *reader, fp *fieldpath) {
	fp.index[len(fp.index)-1] += 1
}

func PlusTwo(r *reader, fp *fieldpath) {
	fp.index[len(fp.index)-1] += 2
}

func PlusThree(r *reader, fp *fieldpath) {
	fp.index[len(fp.index)-1] += 3
}

func PlusFour(r *reader, fp *fieldpath) {
	fp.index[len(fp.index)-1] += 4
}

func PlusN(r *reader, fp *fieldpath) {

}

func PushOneLeftDeltaZeroRightZero(r *reader, fp *fieldpath) {

}

func PushOneLeftDeltaZeroRightNonZero(r *reader, fp *fieldpath) {

}

func PushOneLeftDeltaOneRightZero(r *reader, fp *fieldpath) {

}

func PushOneLeftDeltaOneRightNonZero(r *reader, fp *fieldpath) {

}

func PushOneLeftDeltaNRightZero(r *reader, fp *fieldpath) {

}

func PushOneLeftDeltaNRightNonZero(r *reader, fp *fieldpath) {

}

func PushOneLeftDeltaNRightNonZeroPack6Bits(r *reader, fp *fieldpath) {

}

func PushOneLeftDeltaNRightNonZeroPack8Bits(r *reader, fp *fieldpath) {

}

func PushTwoLeftDeltaZero(r *reader, fp *fieldpath) {

}

func PushTwoLeftDeltaOne(r *reader, fp *fieldpath) {

}

func PushTwoLeftDeltaN(r *reader, fp *fieldpath) {

}

func PushTwoPack5LeftDeltaZero(r *reader, fp *fieldpath) {

}

func PushTwoPack5LeftDeltaOne(r *reader, fp *fieldpath) {

}

func PushTwoPack5LeftDeltaN(r *reader, fp *fieldpath) {

}

func PushThreeLeftDeltaZero(r *reader, fp *fieldpath) {

}

func PushThreeLeftDeltaOne(r *reader, fp *fieldpath) {

}

func PushThreeLeftDeltaN(r *reader, fp *fieldpath) {

}

func PushThreePack5LeftDeltaZero(r *reader, fp *fieldpath) {

}

func PushThreePack5LeftDeltaOne(r *reader, fp *fieldpath) {

}

func PushThreePack5LeftDeltaN(r *reader, fp *fieldpath) {

}

func PushN(r *reader, fp *fieldpath) {

}

func PushNAndNonTopological(r *reader, fp *fieldpath) {

}

func PopOnePlusOne(r *reader, fp *fieldpath) {

}

func PopOnePlusN(r *reader, fp *fieldpath) {

}

func PopAllButOnePlusOne(r *reader, fp *fieldpath) {

}

func PopAllButOnePlusN(r *reader, fp *fieldpath) {

}

func PopAllButOnePlusNPackN(r *reader, fp *fieldpath) {

}

func PopAllButOnePlusNPack3Bits(r *reader, fp *fieldpath) {

}

func PopAllButOnePlusNPack6Bits(r *reader, fp *fieldpath) {

}

func PopNPlusOne(r *reader, fp *fieldpath) {

}

func PopNPlusN(r *reader, fp *fieldpath) {

}

func PopNAndNonTopographical(r *reader, fp *fieldpath) {

}

func NonTopoComplex(r *reader, fp *fieldpath) {

}

func NonTopoPenultimatePlusOne(r *reader, fp *fieldpath) {

}

func NonTopoComplexPack4Bits(r *reader, fp *fieldpath) {

}

func FieldPathEncodeFinish(r *reader, fp *fieldpath) {
	fp.finished = true
}
<|endoftext|>


<commit_before>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package pflag_test

import (
	"bytes"
	. "pflag"
	"fmt"
	"os"
	"sort"
	"strings"
	"testing"
	"time"
)

var (
	test_bool     = Bool("test_bool", false, "bool value")
	test_int      = Int("test_int", 0, "int value")
	test_int64    = Int64("test_int64", 0, "int64 value")
	test_uint     = Uint("test_uint", 0, "uint value")
	test_uint64   = Uint64("test_uint64", 0, "uint64 value")
	test_string   = String("test_string", "0", "string value")
	test_float64  = Float64("test_float64", 0, "float64 value")
	test_duration = Duration("test_duration", 0, "time.Duration value")
)

func boolString(s string) string {
	if s == "0" {
		return "false"
	}
	return "true"
}

func TestEverything(t *testing.T) {
	m := make(map[string]*Flag)
	desired := "0"
	visitor := func(f *Flag) {
		if len(f.Name) > 5 && f.Name[0:5] == "test_" {
			m[f.Name] = f
			ok := false
			switch {
			case f.Value.String() == desired:
				ok = true
			case f.Name == "test_bool" && f.Value.String() == boolString(desired):
				ok = true
			case f.Name == "test_duration" && f.Value.String() == desired+"s":
				ok = true
			}
			if !ok {
				t.Error("Visit: bad value", f.Value.String(), "for", f.Name)
			}
		}
	}
	VisitAll(visitor)
	if len(m) != 8 {
		t.Error("VisitAll misses some flags")
		for k, v := range m {
			t.Log(k, *v)
		}
	}
	m = make(map[string]*Flag)
	Visit(visitor)
	if len(m) != 0 {
		t.Errorf("Visit sees unset flags")
		for k, v := range m {
			t.Log(k, *v)
		}
	}
	// Now set all flags
	Set("test_bool", "true")
	Set("test_int", "1")
	Set("test_int64", "1")
	Set("test_uint", "1")
	Set("test_uint64", "1")
	Set("test_string", "1")
	Set("test_float64", "1")
	Set("test_duration", "1s")
	desired = "1"
	Visit(visitor)
	if len(m) != 8 {
		t.Error("Visit fails after set")
		for k, v := range m {
			t.Log(k, *v)
		}
	}
	// Now test they're visited in sort order.
	var flagNames []string
	Visit(func(f *Flag) { flagNames = append(flagNames, f.Name) })
	if !sort.StringsAreSorted(flagNames) {
		t.Errorf("flag names not sorted: %v", flagNames)
	}
}

func TestUsage(t *testing.T) {
	called := false
	ResetForTesting(func() { called = true })
	if CommandLine().Parse([]string{"-x"}) == nil {
		t.Error("parse did not fail for unknown flag")
	}
	if !called {
		t.Error("did not call Usage for unknown flag")
	}
}

func testParse(f *FlagSet, t *testing.T) {
	if f.Parsed() {
		t.Error("f.Parse() = true before Parse")
	}
	boolFlag := f.Bool("bool", false, "bool value")
	bool2Flag := f.Bool("bool2", false, "bool2 value")
	intFlag := f.Int("int", 0, "int value")
	int64Flag := f.Int64("int64", 0, "int64 value")
	uintFlag := f.Uint("uint", 0, "uint value")
	uint64Flag := f.Uint64("uint64", 0, "uint64 value")
	stringFlag := f.String("string", "0", "string value")
	float64Flag := f.Float64("float64", 0, "float64 value")
	durationFlag := f.Duration("duration", 5*time.Second, "time.Duration value")
	extra := "one-extra-argument"
	args := []string{
		"-bool",
		"-bool2=true",
		"--int", "22",
		"--int64", "0x23",
		"-uint", "24",
		"--uint64", "25",
		"-string", "hello",
		"-float64", "2718e28",
		"-duration", "2m",
		extra,
	}
	if err := f.Parse(args); err != nil {
		t.Fatal(err)
	}
	if !f.Parsed() {
		t.Error("f.Parse() = false after Parse")
	}
	if *boolFlag != true {
		t.Error("bool flag should be true, is ", *boolFlag)
	}
	if *bool2Flag != true {
		t.Error("bool2 flag should be true, is ", *bool2Flag)
	}
	if *intFlag != 22 {
		t.Error("int flag should be 22, is ", *intFlag)
	}
	if *int64Flag != 0x23 {
		t.Error("int64 flag should be 0x23, is ", *int64Flag)
	}
	if *uintFlag != 24 {
		t.Error("uint flag should be 24, is ", *uintFlag)
	}
	if *uint64Flag != 25 {
		t.Error("uint64 flag should be 25, is ", *uint64Flag)
	}
	if *stringFlag != "hello" {
		t.Error("string flag should be `hello`, is ", *stringFlag)
	}
	if *float64Flag != 2718e28 {
		t.Error("float64 flag should be 2718e28, is ", *float64Flag)
	}
	if *durationFlag != 2*time.Minute {
		t.Error("duration flag should be 2m, is ", *durationFlag)
	}
	if len(f.Args()) != 1 {
		t.Error("expected one argument, got", len(f.Args()))
	} else if f.Args()[0] != extra {
		t.Errorf("expected argument %q got %q", extra, f.Args()[0])
	}
}

func TestParse(t *testing.T) {
	ResetForTesting(func() { t.Error("bad parse") })
	testParse(CommandLine(), t)
}

func TestFlagSetParse(t *testing.T) {
	testParse(NewFlagSet("test", ContinueOnError), t)
}

// Declare a user-defined flag type.
type flagVar []string

func (f *flagVar) String() string {
	return fmt.Sprint([]string(*f))
}

func (f *flagVar) Set(value string) error {
	*f = append(*f, value)
	return nil
}

func TestUserDefined(t *testing.T) {
	var flags FlagSet
	flags.Init("test", ContinueOnError)
	var v flagVar
	flags.Var(&v, "v", "usage")
	if err := flags.Parse([]string{"-v", "1", "-v", "2", "-v=3"}); err != nil {
		t.Error(err)
	}
	if len(v) != 3 {
		t.Fatal("expected 3 args; got ", len(v))
	}
	expect := "[1 2 3]"
	if v.String() != expect {
		t.Errorf("expected value %q got %q", expect, v.String())
	}
}

func TestSetOutput(t *testing.T) {
	var flags FlagSet
	var buf bytes.Buffer
	flags.SetOutput(&buf)
	flags.Init("test", ContinueOnError)
	flags.Parse([]string{"-unknown"})
	if out := buf.String(); !strings.Contains(out, "-unknown") {
		t.Logf("expected output mentioning unknown; got %q", out)
	}
}

// This tests that one can reset the flags. This still works but not well, and is
// superseded by FlagSet.
func TestChangingArgs(t *testing.T) {
	ResetForTesting(func() { t.Fatal("bad parse") })
	oldArgs := os.Args
	defer func() { os.Args = oldArgs }()
	os.Args = []string{"cmd", "-before", "subcmd", "-after", "args"}
	before := Bool("before", false, "")
	if err := CommandLine().Parse(os.Args[1:]); err != nil {
		t.Fatal(err)
	}
	cmd := Arg(0)
	os.Args = Args()
	after := Bool("after", false, "")
	Parse()
	args := Args()

	if !*before || cmd != "subcmd" || !*after || len(args) != 1 || args[0] != "args" {
		t.Fatalf("expected true subcmd true [args] got %v %v %v %v", *before, cmd, *after, args)
	}
}

// Test that -help invokes the usage message and returns ErrHelp.
func TestHelp(t *testing.T) {
	var helpCalled = false
	fs := NewFlagSet("help test", ContinueOnError)
	fs.Usage = func() { helpCalled = true }
	var flag bool
	fs.BoolVar(&flag, "flag", false, "regular flag")
	// Regular flag invocation should work
	err := fs.Parse([]string{"-flag=true"})
	if err != nil {
		t.Fatal("expected no error; got ", err)
	}
	if !flag {
		t.Error("flag was not set by -flag")
	}
	if helpCalled {
		t.Error("help called for regular flag")
		helpCalled = false // reset for next test
	}
	// Help flag should work as expected.
	err = fs.Parse([]string{"-help"})
	if err == nil {
		t.Fatal("error expected")
	}
	if err != ErrHelp {
		t.Fatal("expected ErrHelp; got ", err)
	}
	if !helpCalled {
		t.Fatal("help was not called")
	}
	// If we define a help flag, that should override.
	var help bool
	fs.BoolVar(&help, "help", false, "help flag")
	helpCalled = false
	err = fs.Parse([]string{"-help"})
	if err != nil {
		t.Fatal("expected no error for defined -help; got ", err)
	}
	if helpCalled {
		t.Fatal("help was called; should not have been for defined help flag")
	}
}
<commit_msg>Fix up tests to use long -- form<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package pflag_test

import (
	"bytes"
	. "pflag"
	"fmt"
	"os"
	"sort"
	"strings"
	"testing"
	"time"
)

var (
	test_bool     = Bool("test_bool", false, "bool value")
	test_int      = Int("test_int", 0, "int value")
	test_int64    = Int64("test_int64", 0, "int64 value")
	test_uint     = Uint("test_uint", 0, "uint value")
	test_uint64   = Uint64("test_uint64", 0, "uint64 value")
	test_string   = String("test_string", "0", "string value")
	test_float64  = Float64("test_float64", 0, "float64 value")
	test_duration = Duration("test_duration", 0, "time.Duration value")
)

func boolString(s string) string {
	if s == "0" {
		return "false"
	}
	return "true"
}

func TestEverything(t *testing.T) {
	m := make(map[string]*Flag)
	desired := "0"
	visitor := func(f *Flag) {
		if len(f.Name) > 5 && f.Name[0:5] == "test_" {
			m[f.Name] = f
			ok := false
			switch {
			case f.Value.String() == desired:
				ok = true
			case f.Name == "test_bool" && f.Value.String() == boolString(desired):
				ok = true
			case f.Name == "test_duration" && f.Value.String() == desired+"s":
				ok = true
			}
			if !ok {
				t.Error("Visit: bad value", f.Value.String(), "for", f.Name)
			}
		}
	}
	VisitAll(visitor)
	if len(m) != 8 {
		t.Error("VisitAll misses some flags")
		for k, v := range m {
			t.Log(k, *v)
		}
	}
	m = make(map[string]*Flag)
	Visit(visitor)
	if len(m) != 0 {
		t.Errorf("Visit sees unset flags")
		for k, v := range m {
			t.Log(k, *v)
		}
	}
	// Now set all flags
	Set("test_bool", "true")
	Set("test_int", "1")
	Set("test_int64", "1")
	Set("test_uint", "1")
	Set("test_uint64", "1")
	Set("test_string", "1")
	Set("test_float64", "1")
	Set("test_duration", "1s")
	desired = "1"
	Visit(visitor)
	if len(m) != 8 {
		t.Error("Visit fails after set")
		for k, v := range m {
			t.Log(k, *v)
		}
	}
	// Now test they're visited in sort order.
	var flagNames []string
	Visit(func(f *Flag) { flagNames = append(flagNames, f.Name) })
	if !sort.StringsAreSorted(flagNames) {
		t.Errorf("flag names not sorted: %v", flagNames)
	}
}

func TestUsage(t *testing.T) {
	called := false
	ResetForTesting(func() { called = true })
	if CommandLine().Parse([]string{"--x"}) == nil {
		t.Error("parse did not fail for unknown flag")
	}
	if !called {
		t.Error("did not call Usage for unknown flag")
	}
}

func testParse(f *FlagSet, t *testing.T) {
	if f.Parsed() {
		t.Error("f.Parse() = true before Parse")
	}
	boolFlag := f.Bool("bool", false, "bool value")
	bool2Flag := f.Bool("bool2", false, "bool2 value")
	intFlag := f.Int("int", 0, "int value")
	int64Flag := f.Int64("int64", 0, "int64 value")
	uintFlag := f.Uint("uint", 0, "uint value")
	uint64Flag := f.Uint64("uint64", 0, "uint64 value")
	stringFlag := f.String("string", "0", "string value")
	float64Flag := f.Float64("float64", 0, "float64 value")
	durationFlag := f.Duration("duration", 5*time.Second, "time.Duration value")
	extra := "one-extra-argument"
	args := []string{
		"--bool",
		"--bool2=true",
		"--int", "22",
		"--int64", "0x23",
		"--uint", "24",
		"--uint64", "25",
		"--string", "hello",
		"--float64", "2718e28",
		"--duration", "2m",
		extra,
	}
	if err := f.Parse(args); err != nil {
		t.Fatal(err)
	}
	if !f.Parsed() {
		t.Error("f.Parse() = false after Parse")
	}
	if *boolFlag != true {
		t.Error("bool flag should be true, is ", *boolFlag)
	}
	if *bool2Flag != true {
		t.Error("bool2 flag should be true, is ", *bool2Flag)
	}
	if *intFlag != 22 {
		t.Error("int flag should be 22, is ", *intFlag)
	}
	if *int64Flag != 0x23 {
		t.Error("int64 flag should be 0x23, is ", *int64Flag)
	}
	if *uintFlag != 24 {
		t.Error("uint flag should be 24, is ", *uintFlag)
	}
	if *uint64Flag != 25 {
		t.Error("uint64 flag should be 25, is ", *uint64Flag)
	}
	if *stringFlag != "hello" {
		t.Error("string flag should be `hello`, is ", *stringFlag)
	}
	if *float64Flag != 2718e28 {
		t.Error("float64 flag should be 2718e28, is ", *float64Flag)
	}
	if *durationFlag != 2*time.Minute {
		t.Error("duration flag should be 2m, is ", *durationFlag)
	}
	if len(f.Args()) != 1 {
		t.Error("expected one argument, got", len(f.Args()))
	} else if f.Args()[0] != extra {
		t.Errorf("expected argument %q got %q", extra, f.Args()[0])
	}
}

func TestParse(t *testing.T) {
	ResetForTesting(func() { t.Error("bad parse") })
	testParse(CommandLine(), t)
}

func TestFlagSetParse(t *testing.T) {
	testParse(NewFlagSet("test", ContinueOnError), t)
}

// Declare a user-defined flag type.
type flagVar []string

func (f *flagVar) String() string {
	return fmt.Sprint([]string(*f))
}

func (f *flagVar) Set(value string) error {
	*f = append(*f, value)
	return nil
}

func TestUserDefined(t *testing.T) {
	var flags FlagSet
	flags.Init("test", ContinueOnError)
	var v flagVar
	flags.Var(&v, "v", "usage")
	if err := flags.Parse([]string{"--v", "1", "--v", "2", "--v=3"}); err != nil {
		t.Error(err)
	}
	if len(v) != 3 {
		t.Fatal("expected 3 args; got ", len(v))
	}
	expect := "[1 2 3]"
	if v.String() != expect {
		t.Errorf("expected value %q got %q", expect, v.String())
	}
}

func TestSetOutput(t *testing.T) {
	var flags FlagSet
	var buf bytes.Buffer
	flags.SetOutput(&buf)
	flags.Init("test", ContinueOnError)
	flags.Parse([]string{"--unknown"})
	if out := buf.String(); !strings.Contains(out, "--unknown") {
		t.Logf("expected output mentioning unknown; got %q", out)
	}
}

// This tests that one can reset the flags. This still works but not well, and is
// superseded by FlagSet.
func TestChangingArgs(t *testing.T) {
	ResetForTesting(func() { panic("ouch") })//t.Fatal("bad parse") })
	oldArgs := os.Args
	defer func() { os.Args = oldArgs }()
	os.Args = []string{"cmd", "--before", "subcmd", "--after", "args"}
	before := Bool("before", false, "")
	if err := CommandLine().Parse(os.Args[1:]); err != nil {
		t.Fatal(err)
	}
	cmd := Arg(0)
	os.Args = Args()
	after := Bool("after", false, "")
	Parse()
	args := Args()

	if !*before || cmd != "subcmd" || !*after || len(args) != 1 || args[0] != "args" {
		t.Fatalf("expected true subcmd true [args] got %v %v %v %v", *before, cmd, *after, args)
	}
}

// Test that -help invokes the usage message and returns ErrHelp.
func TestHelp(t *testing.T) {
	var helpCalled = false
	fs := NewFlagSet("help test", ContinueOnError)
	fs.Usage = func() { helpCalled = true }
	var flag bool
	fs.BoolVar(&flag, "flag", false, "regular flag")
	// Regular flag invocation should work
	err := fs.Parse([]string{"--flag=true"})
	if err != nil {
		t.Fatal("expected no error; got ", err)
	}
	if !flag {
		t.Error("flag was not set by --flag")
	}
	if helpCalled {
		t.Error("help called for regular flag")
		helpCalled = false // reset for next test
	}
	// Help flag should work as expected.
	err = fs.Parse([]string{"--help"})
	if err == nil {
		t.Fatal("error expected")
	}
	if err != ErrHelp {
		t.Fatal("expected ErrHelp; got ", err)
	}
	if !helpCalled {
		t.Fatal("help was not called")
	}
	// If we define a help flag, that should override.
	var help bool
	fs.BoolVar(&help, "help", false, "help flag")
	helpCalled = false
	err = fs.Parse([]string{"--help"})
	if err != nil {
		t.Fatal("expected no error for defined --help; got ", err)
	}
	if helpCalled {
		t.Fatal("help was called; should not have been for defined help flag")
	}
}
<|endoftext|>


<commit_before>// Package tinystat provides the ability to compare data sets using Student's
// t-test at various levels of confidence.
package tinystat

import (
	"math"

	"gonum.org/v1/gonum/stat/distuv"
)

// A Summary is a statistical summary of a normally distributed data set.
type Summary struct {
	N        float64 // N is the number of measurements in the set.
	Mean     float64 // Mean is the arithmetic mean of the measurements.
	Variance float64 // Variance is the sample variance of the data set.
}

// Summarize analyzes the given data set and returns a Summary.
func Summarize(data []float64) Summary {
	n := float64(len(data))
	m, v := meanAndVariance(data, n)

	return Summary{Mean: m, Variance: v, N: n}
}

// Difference represents the statistical difference between two samples.
type Difference struct {
	Delta    float64 // Delta is the difference between the samples' means.
	Error    float64 // Error is the margin of error at the given confidence level.
	RelDelta float64 // RelDelta is the ratio of Delta to the control mean.
	RelError float64 // RelError is the ratio of Error to the control mean.
	StdDev   float64 // StdDev is the pooled standard deviation of the two samples.
}

// Significant returns true if the difference is statistically significant.
func (d Difference) Significant() bool {
	return d.Delta > d.Error
}

// Compare returns the statistical difference between the two summaries using a
// two-tailed Student's t-test. The confidence level must be in the range (0,
// 100).
func Compare(control, experiment Summary, confidence float64) Difference {
	a, b := control, experiment
	nu := a.N + b.N - 2
	t := studentsTQuantile(nu, confidence)
	s := math.Sqrt(((a.N-1)*a.Variance + (b.N-1)*b.Variance) / nu)
	d := math.Abs(a.Mean - b.Mean)
	e := t * s * math.Sqrt(1.0/a.N+1.0/b.N)

	return Difference{
		Delta:    d,
		Error:    e,
		RelDelta: d / control.Mean,
		RelError: e / control.Mean,
		StdDev:   s,
	}
}

func studentsTQuantile(nu float64, confidence float64) float64 {
	return distuv.StudentsT{Mu: 0, Sigma: 1, Nu: nu}.
		Quantile(1 - ((1 - (confidence / 100)) / 2)) // two-tailed test
}

func meanAndVariance(data []float64, n float64) (m float64, v float64) {
	// Welford algorithm for corrected variance
	for i, x := range data {
		delta := x - m
		m += delta / float64(i+1)
		v += delta * (x - m)
	}

	v /= n - 1 // Bessel's correction

	return
}
<commit_msg>Simplify code.<commit_after>// Package tinystat provides the ability to compare data sets using Student's
// t-test at various levels of confidence.
package tinystat

import (
	"math"

	"gonum.org/v1/gonum/stat"
	"gonum.org/v1/gonum/stat/distuv"
)

// A Summary is a statistical summary of a normally distributed data set.
type Summary struct {
	N        float64 // N is the number of measurements in the set.
	Mean     float64 // Mean is the arithmetic mean of the measurements.
	Variance float64 // Variance is the sample variance of the data set.
}

// Summarize analyzes the given data set and returns a Summary.
func Summarize(data []float64) Summary {
	m, v := stat.MeanVariance(data, nil)

	return Summary{Mean: m, Variance: v, N: float64(len(data))}
}

// Difference represents the statistical difference between two samples.
type Difference struct {
	Delta    float64 // Delta is the difference between the samples' means.
	Error    float64 // Error is the margin of error at the given confidence level.
	RelDelta float64 // RelDelta is the ratio of Delta to the control mean.
	RelError float64 // RelError is the ratio of Error to the control mean.
	StdDev   float64 // StdDev is the pooled standard deviation of the two samples.
}

// Significant returns true if the difference is statistically significant.
func (d Difference) Significant() bool {
	return d.Delta > d.Error
}

// Compare returns the statistical difference between the two summaries using a
// two-tailed Student's t-test. The confidence level must be in the range (0,
// 100).
func Compare(control, experiment Summary, confidence float64) Difference {
	a, b := control, experiment
	nu := a.N + b.N - 2
	t := distuv.StudentsT{Mu: 0, Sigma: 1, Nu: nu}.
		Quantile(1 - ((1 - (confidence / 100)) / 2)) // two-tailed test
	s := math.Sqrt(((a.N-1)*a.Variance + (b.N-1)*b.Variance) / nu)
	d := math.Abs(a.Mean - b.Mean)
	e := t * s * math.Sqrt(1.0/a.N+1.0/b.N)

	return Difference{
		Delta:    d,
		Error:    e,
		RelDelta: d / control.Mean,
		RelError: e / control.Mean,
		StdDev:   s,
	}
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"crypto/tls"
	"flag"
	"net"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"

	"github.com/coreos/go-semver/semver"
	"github.com/fnproject/fn/fnlb/lb"
	"github.com/sirupsen/logrus"
)

const VERSION = "0.0.126"

func main() {
	// XXX (reed): normalize
	fnodes := flag.String("nodes", "", "comma separated list of functions nodes")
	minAPIVersion := flag.String("min-api-version", "0.0.93", "minimal node API to accept")

	var conf lb.Config
	flag.StringVar(&conf.DBurl, "db", "sqlite3://:memory:", "backend to store nodes, default to in memory")
	flag.StringVar(&conf.Listen, "listen", ":8081", "port to run on")
	flag.IntVar(&conf.HealthcheckInterval, "hc-interval", 3, "how often to check f(x) nodes, in seconds")
	flag.StringVar(&conf.HealthcheckEndpoint, "hc-path", "/version", "endpoint to determine node health")
	flag.IntVar(&conf.HealthcheckUnhealthy, "hc-unhealthy", 2, "threshold of failed checks to declare node unhealthy")
	flag.IntVar(&conf.HealthcheckTimeout, "hc-timeout", 5, "timeout of healthcheck endpoint, in seconds")
	flag.StringVar(&conf.ZipkinURL, "zipkin", "", "zipkin endpoint to send traces")
	flag.Parse()

	conf.MinAPIVersion = semver.New(*minAPIVersion)

	if len(*fnodes) > 0 {
		// starting w/o nodes is fine too
		conf.Nodes = strings.Split(*fnodes, ",")
	}

	conf.Transport = &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		Dial: (&net.Dialer{
			Timeout:   10 * time.Second,
			KeepAlive: 120 * time.Second,
		}).Dial,
		MaxIdleConnsPerHost: 512,
		TLSHandshakeTimeout: 10 * time.Second,
		TLSClientConfig: &tls.Config{
			ClientSessionCache: tls.NewLRUClientSessionCache(4096),
		},
	}

	g, err := lb.NewAllGrouper(conf)
	if err != nil {
		logrus.WithError(err).Fatal("error setting up grouper")
	}

	r := lb.NewConsistentRouter(conf)
	k := func(r *http.Request) (string, error) {
		return r.URL.Path, nil
	}

	h := lb.NewProxy(k, g, r, conf)
	h = g.Wrap(h) // add/del/list endpoints
	h = r.Wrap(h) // stats / dash endpoint

	err = serve(conf.Listen, h)
	if err != nil {
		logrus.WithError(err).Fatal("server error")
	}
}

func serve(addr string, handler http.Handler) error {
	server := &http.Server{Addr: addr, Handler: handler}

	ch := make(chan os.Signal, 1)
	signal.Notify(ch, syscall.SIGQUIT, syscall.SIGINT)
	go func() {
		for sig := range ch {
			logrus.WithFields(logrus.Fields{"signal": sig}).Info("received signal")
			server.Shutdown(context.Background()) // safe shutdown
			return
		}
	}()
	return server.ListenAndServe()
}
<commit_msg>fnlb: 0.0.127 release [skip ci]<commit_after>package main

import (
	"context"
	"crypto/tls"
	"flag"
	"net"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"

	"github.com/coreos/go-semver/semver"
	"github.com/fnproject/fn/fnlb/lb"
	"github.com/sirupsen/logrus"
)

const VERSION = "0.0.127"

func main() {
	// XXX (reed): normalize
	fnodes := flag.String("nodes", "", "comma separated list of functions nodes")
	minAPIVersion := flag.String("min-api-version", "0.0.94", "minimal node API to accept")

	var conf lb.Config
	flag.StringVar(&conf.DBurl, "db", "sqlite3://:memory:", "backend to store nodes, default to in memory")
	flag.StringVar(&conf.Listen, "listen", ":8081", "port to run on")
	flag.IntVar(&conf.HealthcheckInterval, "hc-interval", 3, "how often to check f(x) nodes, in seconds")
	flag.StringVar(&conf.HealthcheckEndpoint, "hc-path", "/version", "endpoint to determine node health")
	flag.IntVar(&conf.HealthcheckUnhealthy, "hc-unhealthy", 2, "threshold of failed checks to declare node unhealthy")
	flag.IntVar(&conf.HealthcheckTimeout, "hc-timeout", 5, "timeout of healthcheck endpoint, in seconds")
	flag.StringVar(&conf.ZipkinURL, "zipkin", "", "zipkin endpoint to send traces")
	flag.Parse()

	conf.MinAPIVersion = semver.New(*minAPIVersion)

	if len(*fnodes) > 0 {
		// starting w/o nodes is fine too
		conf.Nodes = strings.Split(*fnodes, ",")
	}

	conf.Transport = &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		Dial: (&net.Dialer{
			Timeout:   10 * time.Second,
			KeepAlive: 120 * time.Second,
		}).Dial,
		MaxIdleConnsPerHost: 512,
		TLSHandshakeTimeout: 10 * time.Second,
		TLSClientConfig: &tls.Config{
			ClientSessionCache: tls.NewLRUClientSessionCache(4096),
		},
	}

	g, err := lb.NewAllGrouper(conf)
	if err != nil {
		logrus.WithError(err).Fatal("error setting up grouper")
	}

	r := lb.NewConsistentRouter(conf)
	k := func(r *http.Request) (string, error) {
		return r.URL.Path, nil
	}

	h := lb.NewProxy(k, g, r, conf)
	h = g.Wrap(h) // add/del/list endpoints
	h = r.Wrap(h) // stats / dash endpoint

	err = serve(conf.Listen, h)
	if err != nil {
		logrus.WithError(err).Fatal("server error")
	}
}

func serve(addr string, handler http.Handler) error {
	server := &http.Server{Addr: addr, Handler: handler}

	ch := make(chan os.Signal, 1)
	signal.Notify(ch, syscall.SIGQUIT, syscall.SIGINT)
	go func() {
		for sig := range ch {
			logrus.WithFields(logrus.Fields{"signal": sig}).Info("received signal")
			server.Shutdown(context.Background()) // safe shutdown
			return
		}
	}()
	return server.ListenAndServe()
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"crypto/tls"
	"flag"
	"net"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"

	"github.com/sirupsen/logrus"
	"github.com/coreos/go-semver/semver"
	"github.com/fnproject/fn/fnlb/lb"
)

const VERSION = "0.0.54"

func main() {
	// XXX (reed): normalize
	fnodes := flag.String("nodes", "", "comma separated list of functions nodes")
	minAPIVersion := flag.String("min-api-version", "0.0.21", "minimal node API to accept")

	var conf lb.Config
	flag.StringVar(&conf.DBurl, "db", "sqlite3://:memory:", "backend to store nodes, default to in memory")
	flag.StringVar(&conf.Listen, "listen", ":8081", "port to run on")
	flag.IntVar(&conf.HealthcheckInterval, "hc-interval", 3, "how often to check f(x) nodes, in seconds")
	flag.StringVar(&conf.HealthcheckEndpoint, "hc-path", "/version", "endpoint to determine node health")
	flag.IntVar(&conf.HealthcheckUnhealthy, "hc-unhealthy", 2, "threshold of failed checks to declare node unhealthy")
	flag.IntVar(&conf.HealthcheckTimeout, "hc-timeout", 5, "timeout of healthcheck endpoint, in seconds")
	flag.StringVar(&conf.ZipkinURL, "zipkin", "", "zipkin endpoint to send traces")
	flag.Parse()

	conf.MinAPIVersion = semver.New(*minAPIVersion)

	if len(*fnodes) > 0 {
		// starting w/o nodes is fine too
		conf.Nodes = strings.Split(*fnodes, ",")
	}

	conf.Transport = &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		Dial: (&net.Dialer{
			Timeout:   10 * time.Second,
			KeepAlive: 120 * time.Second,
		}).Dial,
		MaxIdleConnsPerHost: 512,
		TLSHandshakeTimeout: 10 * time.Second,
		TLSClientConfig: &tls.Config{
			ClientSessionCache: tls.NewLRUClientSessionCache(4096),
		},
	}

	g, err := lb.NewAllGrouper(conf)
	if err != nil {
		logrus.WithError(err).Fatal("error setting up grouper")
	}

	r := lb.NewConsistentRouter(conf)
	k := func(r *http.Request) (string, error) {
		return r.URL.Path, nil
	}

	h := lb.NewProxy(k, g, r, conf)
	h = g.Wrap(h) // add/del/list endpoints
	h = r.Wrap(h) // stats / dash endpoint

	err = serve(conf.Listen, h)
	if err != nil {
		logrus.WithError(err).Fatal("server error")
	}
}

func serve(addr string, handler http.Handler) error {
	server := &http.Server{Addr: addr, Handler: handler}

	ch := make(chan os.Signal, 1)
	signal.Notify(ch, syscall.SIGQUIT, syscall.SIGINT)
	go func() {
		for sig := range ch {
			logrus.WithFields(logrus.Fields{"signal": sig}).Info("received signal")
			server.Shutdown(context.Background()) // safe shutdown
			return
		}
	}()
	return server.ListenAndServe()
}
<commit_msg>fnlb: 0.0.55 release [skip ci]<commit_after>package main

import (
	"context"
	"crypto/tls"
	"flag"
	"net"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"

	"github.com/sirupsen/logrus"
	"github.com/coreos/go-semver/semver"
	"github.com/fnproject/fn/fnlb/lb"
)

const VERSION = "0.0.55"

func main() {
	// XXX (reed): normalize
	fnodes := flag.String("nodes", "", "comma separated list of functions nodes")
	minAPIVersion := flag.String("min-api-version", "0.0.22", "minimal node API to accept")

	var conf lb.Config
	flag.StringVar(&conf.DBurl, "db", "sqlite3://:memory:", "backend to store nodes, default to in memory")
	flag.StringVar(&conf.Listen, "listen", ":8081", "port to run on")
	flag.IntVar(&conf.HealthcheckInterval, "hc-interval", 3, "how often to check f(x) nodes, in seconds")
	flag.StringVar(&conf.HealthcheckEndpoint, "hc-path", "/version", "endpoint to determine node health")
	flag.IntVar(&conf.HealthcheckUnhealthy, "hc-unhealthy", 2, "threshold of failed checks to declare node unhealthy")
	flag.IntVar(&conf.HealthcheckTimeout, "hc-timeout", 5, "timeout of healthcheck endpoint, in seconds")
	flag.StringVar(&conf.ZipkinURL, "zipkin", "", "zipkin endpoint to send traces")
	flag.Parse()

	conf.MinAPIVersion = semver.New(*minAPIVersion)

	if len(*fnodes) > 0 {
		// starting w/o nodes is fine too
		conf.Nodes = strings.Split(*fnodes, ",")
	}

	conf.Transport = &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		Dial: (&net.Dialer{
			Timeout:   10 * time.Second,
			KeepAlive: 120 * time.Second,
		}).Dial,
		MaxIdleConnsPerHost: 512,
		TLSHandshakeTimeout: 10 * time.Second,
		TLSClientConfig: &tls.Config{
			ClientSessionCache: tls.NewLRUClientSessionCache(4096),
		},
	}

	g, err := lb.NewAllGrouper(conf)
	if err != nil {
		logrus.WithError(err).Fatal("error setting up grouper")
	}

	r := lb.NewConsistentRouter(conf)
	k := func(r *http.Request) (string, error) {
		return r.URL.Path, nil
	}

	h := lb.NewProxy(k, g, r, conf)
	h = g.Wrap(h) // add/del/list endpoints
	h = r.Wrap(h) // stats / dash endpoint

	err = serve(conf.Listen, h)
	if err != nil {
		logrus.WithError(err).Fatal("server error")
	}
}

func serve(addr string, handler http.Handler) error {
	server := &http.Server{Addr: addr, Handler: handler}

	ch := make(chan os.Signal, 1)
	signal.Notify(ch, syscall.SIGQUIT, syscall.SIGINT)
	go func() {
		for sig := range ch {
			logrus.WithFields(logrus.Fields{"signal": sig}).Info("received signal")
			server.Shutdown(context.Background()) // safe shutdown
			return
		}
	}()
	return server.ListenAndServe()
}
<|endoftext|>


<commit_before>package pretty

import (
	"fmt"
	"io"
	"reflect"
)

const (
	limit = 50
)

var (
	commaLFBytes     = []byte(",\n")
	curlyBytes       = []byte("{}")
	openCurlyLFBytes = []byte("{\n")
	spacePlusLFBytes = []byte(" +\n")
)

type formatter struct {
	d int
	x interface{}

	omit bool
}

// Formatter makes a wrapper, f, that will format x as go source with line
// breaks and tabs. Object f responds to the "%v" formatting verb when both the
// "#" and " " (space) flags are set, for example:
//
//     fmt.Sprintf("%# v", Formatter(x))
//
// If one of these two flags is not set, or any other verb is used, f will
// format x according to the usual rules of package fmt.
// In particular, if x satisfies fmt.Formatter, then x.Format will be called.
func Formatter(x interface{}) (f fmt.Formatter) {
	return formatter{x: x}
}

func (fo formatter) String() string {
	return fmt.Sprint(fo.x) // unwrap it
}

func (fo formatter) passThrough(f fmt.State, c int) {
	s := "%"
	for i := 0; i < 128; i++ {
		if f.Flag(i) {
			s += string(i)
		}
	}
	if w, ok := f.Width(); ok {
		s += fmt.Sprintf("%d", w)
	}
	if p, ok := f.Precision(); ok {
		s += fmt.Sprintf(".%d", p)
	}
	s += string(c)
	fmt.Fprintf(f, s, fo.x)
}

func (fo formatter) Format(f fmt.State, c int) {
	if c == 'v' && f.Flag('#') && f.Flag(' ') {
		fo.format(f)
		return
	}
	fo.passThrough(f, c)
}

func (fo formatter) format(w io.Writer) {
	v := reflect.ValueOf(fo.x)
	switch v.Kind() {
	case reflect.String:
		lim := limit - 8*fo.d
		s := v.String()
		z := len(s)
		n := (z + lim - 1) / lim
		if n < 1 {
			n = 1 // empty string still produces output
		}
		sep := append(spacePlusLFBytes, make([]byte, fo.d)...)
		for j := 0; j < fo.d; j++ {
			sep[3+j] = '\t'
		}
		for i := 0; i < n; i++ {
			if i > 0 {
				w.Write(sep)
			}
			l, h := i*lim, (i+1)*lim
			if h > z {
				h = z
			}
			fmt.Fprintf(w, "%#v", s[l:h])
		}
		return
	case reflect.Ptr:
		e := v.Elem()
		if !e.IsValid() {
			fmt.Fprintf(w, "%#v", fo.x)
		} else {
			writeByte(w, '&')
			fmt.Fprintf(w, "%# v", formatter{d: fo.d, x: e.Interface()})
		}
	case reflect.Slice:
		s := fmt.Sprintf("%#v", fo.x)
		if len(s) < limit {
			io.WriteString(w, s)
			return
		}

		t := v.Type()

		io.WriteString(w, reflect.TypeOf(fo.x).String())
		w.Write(openCurlyLFBytes)
		for i := 0; i < v.Len(); i++ {
			for j := 0; j < fo.d+1; j++ {
				writeByte(w, '\t')
			}
			inner := formatter{d: fo.d + 1, x: v.Index(i).Interface(), omit: t.Elem().Kind() != reflect.Interface}
			fmt.Fprintf(w, "%# v", inner)
			w.Write(commaLFBytes)
		}
		for j := 0; j < fo.d; j++ {
			writeByte(w, '\t')
		}
		writeByte(w, '}')
	case reflect.Struct:
		t := v.Type()
		if reflect.DeepEqual(reflect.Zero(t).Interface(), fo.x) {
			if !fo.omit {
				io.WriteString(w, t.String())
			}
			w.Write(curlyBytes)
			return
		}

		s := fmt.Sprintf("%#v", fo.x)
		if fo.omit {
			s = s[len(t.String()):]
		}
		if len(s) < limit {
			io.WriteString(w, s)
			return
		}

		if !fo.omit {
			io.WriteString(w, t.String())
		}
		w.Write(openCurlyLFBytes)
		var max int
		for i := 0; i < v.NumField(); i++ {
			if v := t.Field(i); v.Name != "" {
				if len(v.Name)+2 > max {
					max = len(v.Name) + 2
				}
			}
		}
		for i := 0; i < v.NumField(); i++ {
			if f := t.Field(i); f.Name != "" {
				for j := 0; j < fo.d+1; j++ {
					writeByte(w, '\t')
				}
				io.WriteString(w, f.Name)
				writeByte(w, ':')
				for j := len(f.Name) + 1; j < max; j++ {
					writeByte(w, ' ')
				}
				inner := formatter{d: fo.d + 1, x: v.Field(i).Interface()}
				io.WriteString(w, fmt.Sprintf("%# v", inner))
				w.Write(commaLFBytes)
			}
		}
		for j := 0; j < fo.d; j++ {
			writeByte(w, '\t')
		}
		writeByte(w, '}')
	default:
		fmt.Fprintf(w, "%#v", fo.x)
	}
}

func writeByte(w io.Writer, b byte) {
	w.Write([]byte{b})
}
<commit_msg>fixes for weekly.2011-12-22<commit_after>package pretty

import (
	"fmt"
	"io"
	"reflect"
)

const (
	limit = 50
)

var (
	commaLFBytes     = []byte(",\n")
	curlyBytes       = []byte("{}")
	openCurlyLFBytes = []byte("{\n")
	spacePlusLFBytes = []byte(" +\n")
)

type formatter struct {
	d int
	x interface{}

	omit bool
}

// Formatter makes a wrapper, f, that will format x as go source with line
// breaks and tabs. Object f responds to the "%v" formatting verb when both the
// "#" and " " (space) flags are set, for example:
//
//     fmt.Sprintf("%# v", Formatter(x))
//
// If one of these two flags is not set, or any other verb is used, f will
// format x according to the usual rules of package fmt.
// In particular, if x satisfies fmt.Formatter, then x.Format will be called.
func Formatter(x interface{}) (f fmt.Formatter) {
	return formatter{x: x}
}

func (fo formatter) String() string {
	return fmt.Sprint(fo.x) // unwrap it
}

func (fo formatter) passThrough(f fmt.State, c rune) {
	s := "%"
	for i := 0; i < 128; i++ {
		if f.Flag(i) {
			s += string(i)
		}
	}
	if w, ok := f.Width(); ok {
		s += fmt.Sprintf("%d", w)
	}
	if p, ok := f.Precision(); ok {
		s += fmt.Sprintf(".%d", p)
	}
	s += string(c)
	fmt.Fprintf(f, s, fo.x)
}

func (fo formatter) Format(f fmt.State, c rune) {
	if c == 'v' && f.Flag('#') && f.Flag(' ') {
		fo.format(f)
		return
	}
	fo.passThrough(f, c)
}

func (fo formatter) format(w io.Writer) {
	v := reflect.ValueOf(fo.x)
	switch v.Kind() {
	case reflect.String:
		lim := limit - 8*fo.d
		s := v.String()
		z := len(s)
		n := (z + lim - 1) / lim
		if n < 1 {
			n = 1 // empty string still produces output
		}
		sep := append(spacePlusLFBytes, make([]byte, fo.d)...)
		for j := 0; j < fo.d; j++ {
			sep[3+j] = '\t'
		}
		for i := 0; i < n; i++ {
			if i > 0 {
				w.Write(sep)
			}
			l, h := i*lim, (i+1)*lim
			if h > z {
				h = z
			}
			fmt.Fprintf(w, "%#v", s[l:h])
		}
		return
	case reflect.Ptr:
		e := v.Elem()
		if !e.IsValid() {
			fmt.Fprintf(w, "%#v", fo.x)
		} else {
			writeByte(w, '&')
			fmt.Fprintf(w, "%# v", formatter{d: fo.d, x: e.Interface()})
		}
	case reflect.Slice:
		s := fmt.Sprintf("%#v", fo.x)
		if len(s) < limit {
			io.WriteString(w, s)
			return
		}

		t := v.Type()

		io.WriteString(w, reflect.TypeOf(fo.x).String())
		w.Write(openCurlyLFBytes)
		for i := 0; i < v.Len(); i++ {
			for j := 0; j < fo.d+1; j++ {
				writeByte(w, '\t')
			}
			inner := formatter{d: fo.d + 1, x: v.Index(i).Interface(), omit: t.Elem().Kind() != reflect.Interface}
			fmt.Fprintf(w, "%# v", inner)
			w.Write(commaLFBytes)
		}
		for j := 0; j < fo.d; j++ {
			writeByte(w, '\t')
		}
		writeByte(w, '}')
	case reflect.Struct:
		t := v.Type()
		if reflect.DeepEqual(reflect.Zero(t).Interface(), fo.x) {
			if !fo.omit {
				io.WriteString(w, t.String())
			}
			w.Write(curlyBytes)
			return
		}

		s := fmt.Sprintf("%#v", fo.x)
		if fo.omit {
			s = s[len(t.String()):]
		}
		if len(s) < limit {
			io.WriteString(w, s)
			return
		}

		if !fo.omit {
			io.WriteString(w, t.String())
		}
		w.Write(openCurlyLFBytes)
		var max int
		for i := 0; i < v.NumField(); i++ {
			if v := t.Field(i); v.Name != "" {
				if len(v.Name)+2 > max {
					max = len(v.Name) + 2
				}
			}
		}
		for i := 0; i < v.NumField(); i++ {
			if f := t.Field(i); f.Name != "" {
				for j := 0; j < fo.d+1; j++ {
					writeByte(w, '\t')
				}
				io.WriteString(w, f.Name)
				writeByte(w, ':')
				for j := len(f.Name) + 1; j < max; j++ {
					writeByte(w, ' ')
				}
				inner := formatter{d: fo.d + 1, x: v.Field(i).Interface()}
				io.WriteString(w, fmt.Sprintf("%# v", inner))
				w.Write(commaLFBytes)
			}
		}
		for j := 0; j < fo.d; j++ {
			writeByte(w, '\t')
		}
		writeByte(w, '}')
	default:
		fmt.Fprintf(w, "%#v", fo.x)
	}
}

func writeByte(w io.Writer, b byte) {
	w.Write([]byte{b})
}
<|endoftext|>


<commit_before>package prefixed

import (
	"bytes"
	"fmt"
	"io"
	"regexp"
	"runtime"
	"sort"
	"strings"
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/mgutz/ansi"
)

const reset = ansi.Reset

var (
	baseTimestamp time.Time
	isTerminal    bool
)

func init() {
	baseTimestamp = time.Now()
	isTerminal = logrus.IsTerminal()
}

func miniTS() int {
	return int(time.Since(baseTimestamp) / time.Second)
}

// TextFormatter is the prefixed version of logrus.TextFormatter
type TextFormatter struct {
	// Set to true to bypass checking for a TTY before outputting colors.
	ForceColors bool

	// Force disabling colors.
	DisableColors bool

	// Disable timestamp logging. useful when output is redirected to logging
	// system that already adds timestamps.
	DisableTimestamp bool

	// Enable logging of just the time passed since beginning of execution.
	ShortTimestamp bool

	// The fields are sorted by default for a consistent output. For
	// applications that log extremely frequently and don't use the JSON
	// formatter this may not be desired.
	DisableSorting bool

	// Indent multi-line messages by the timestamp length to preserve proper
	// alignment
	IndentMultilineMessage bool

	// Timestamp format to use for display when a full timestamp is printed.
	TimestampFormat string

	// Pad msg field with spaces on the right for display. The value for this
	// parameter will be the size of padding. Its default value is zero, which
	// means no padding will be applied for msg.
	SpacePadding int
}

func (f *TextFormatter) Format(entry *logrus.Entry) ([]byte, error) {
	keys := make([]string, 0, len(entry.Data))
	for k := range entry.Data {
		if k != "prefix" {
			keys = append(keys, k)
		}
	}

	if !f.DisableSorting {
		sort.Strings(keys)
	}

	b := &bytes.Buffer{}

	prefixFieldClashes(entry.Data)

	isColorTerminal := isTerminal && (runtime.GOOS != "windows")
	isColored := (f.ForceColors || isColorTerminal) && !f.DisableColors

	timestampFormat := f.TimestampFormat
	if timestampFormat == "" {
		timestampFormat = time.Stamp
	}
	if isColored {
		f.printColored(b, entry, keys, timestampFormat)
	} else {
		if !f.DisableTimestamp {
			f.appendKeyValue(b, "time", entry.Time.Format(timestampFormat))
		}
		f.appendKeyValue(b, "level", entry.Level.String())
		if entry.Message != "" {
			f.appendKeyValue(b, "msg", entry.Message)
		}
		for _, key := range keys {
			f.appendKeyValue(b, key, entry.Data[key])
		}
	}

	b.WriteByte('\n')
	return b.Bytes(), nil
}

func (f *TextFormatter) printColored(wr io.Writer, entry *logrus.Entry,
	keys []string, timestampFormat string) {
	var levelColor string
	var levelText string
	var debugInf string
	switch entry.Level {
	case logrus.InfoLevel:
		levelColor = ansi.Green
	case logrus.WarnLevel:
		levelColor = ansi.Yellow
	case logrus.ErrorLevel, logrus.FatalLevel, logrus.PanicLevel:
		levelColor = ansi.Red
	case logrus.DebugLevel:
		pc, file, line,_ := runtime.Caller(6)

		callername := runtime.FuncForPC(pc).Name()
		debugInf = fmt.Sprintf(" [%s][%s][%d]", callername, file, line)
		fallthrough
	default:
		levelColor = ansi.Blue
	}

	if entry.Level != logrus.WarnLevel {
		levelText = strings.ToUpper(entry.Level.String())
	} else {
		levelText = "WARN"
	}

	prefix := ""
	message := entry.Message

	if pfx, ok := entry.Data["prefix"]; ok {
		prefix = fmt.Sprint(" ", ansi.Cyan, pfx, ":", reset)
	} else if pfx, trimmed := extractPrefix(entry.Message); len(pfx) > 0 {
		prefix = fmt.Sprint(" ", ansi.Cyan, pfx, ":", reset)
		message = trimmed
	}

	messageFormat := "%s"
	if f.SpacePadding != 0 {
		messageFormat = fmt.Sprintf("%%-%ds", f.SpacePadding)
	}

	// Remember how many bytes we've written to the buffer (i.e. how long the
	// timestamp, etc. is).
	var padlen int
	if f.DisableTimestamp {
		padlen, _ = fmt.Fprintf(wr, "%s%s %s%+5s%s%s%s ", ansi.LightBlack, reset,
			levelColor, levelText, reset, debugInf, prefix)
	} else {
		if f.ShortTimestamp {
			padlen, _ = fmt.Fprintf(wr, "%s[%04d]%s %s%+5s%s%s%s ",
				ansi.LightBlack, miniTS(), reset, levelColor, levelText, reset,
				debugInf, prefix)
		} else {
			padlen, _ = fmt.Fprintf(wr, "%s[%s]%s %s%+5s%s%s%s ", ansi.LightBlack,
				entry.Time.Format(timestampFormat), reset, levelColor,
				levelText, reset, debugInf, prefix)
		}
	}

	if f.IndentMultilineMessage && strings.ContainsRune(message, '\n') {
		// here we subtract the length of the used control characters
		padlen -= len(ansi.LightBlack) + len(levelColor) + 2 * len(reset)
		if prefix != "" {
			padlen -= len(ansi.Cyan) + len(reset)
		}
		fmt.Fprintf(wr, messageFormat, strings.Replace(message, "\n", "\n" +
			strings.Repeat(" ", padlen), -1))
	} else {
		fmt.Fprintf(wr, messageFormat, message)
	}

	for _, k := range keys {
		v := entry.Data[k]
		fmt.Fprintf(wr, " %s%s%s=%+v", levelColor, k, reset, v)
	}
}

func needsQuoting(text string) bool {
	for _, ch := range text {
		if !((ch >= 'a' && ch <= 'z') ||
			(ch >= 'A' && ch <= 'Z') ||
			(ch >= '0' && ch <= '9') ||
			ch == '-' || ch == '.') {
			return false
		}
	}
	return true
}

func extractPrefix(msg string) (string, string) {
	prefix := ""
	regex := regexp.MustCompile(`^\[(.*?)\]`)
	if regex.MatchString(msg) {
		match := regex.FindString(msg)
		prefix, msg = match[1:len(match)-1], strings.TrimSpace(msg[len(match):])
	}
	return prefix, msg
}

func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string,
	value interface{}) {
	b.WriteString(key)
	b.WriteByte('=')

	switch value := value.(type) {
	case string:
		if needsQuoting(value) {
			b.WriteString(value)
		} else {
			fmt.Fprintf(b, "%q", value)
		}
	case error:
		errmsg := value.Error()
		if needsQuoting(errmsg) {
			b.WriteString(errmsg)
		} else {
			fmt.Fprintf(b, "%q", value)
		}
	default:
		fmt.Fprint(b, value)
	}

	b.WriteByte(' ')
}

func prefixFieldClashes(data logrus.Fields) {
	_, ok := data["time"]
	if ok {
		data["fields.time"] = data["time"]
	}
	_, ok = data["msg"]
	if ok {
		data["fields.msg"] = data["msg"]
	}
	_, ok = data["level"]
	if ok {
		data["fields.level"] = data["level"]
	}
}
<commit_msg>go fmt<commit_after>package prefixed

import (
	"bytes"
	"fmt"
	"io"
	"regexp"
	"runtime"
	"sort"
	"strings"
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/mgutz/ansi"
)

const reset = ansi.Reset

var (
	baseTimestamp time.Time
	isTerminal    bool
)

func init() {
	baseTimestamp = time.Now()
	isTerminal = logrus.IsTerminal()
}

func miniTS() int {
	return int(time.Since(baseTimestamp) / time.Second)
}

// TextFormatter is the prefixed version of logrus.TextFormatter
type TextFormatter struct {
	// Set to true to bypass checking for a TTY before outputting colors.
	ForceColors bool

	// Force disabling colors.
	DisableColors bool

	// Disable timestamp logging. useful when output is redirected to logging
	// system that already adds timestamps.
	DisableTimestamp bool

	// Enable logging of just the time passed since beginning of execution.
	ShortTimestamp bool

	// The fields are sorted by default for a consistent output. For
	// applications that log extremely frequently and don't use the JSON
	// formatter this may not be desired.
	DisableSorting bool

	// Indent multi-line messages by the timestamp length to preserve proper
	// alignment
	IndentMultilineMessage bool

	// Timestamp format to use for display when a full timestamp is printed.
	TimestampFormat string

	// Pad msg field with spaces on the right for display. The value for this
	// parameter will be the size of padding. Its default value is zero, which
	// means no padding will be applied for msg.
	SpacePadding int
}

func (f *TextFormatter) Format(entry *logrus.Entry) ([]byte, error) {
	keys := make([]string, 0, len(entry.Data))
	for k := range entry.Data {
		if k != "prefix" {
			keys = append(keys, k)
		}
	}

	if !f.DisableSorting {
		sort.Strings(keys)
	}

	b := &bytes.Buffer{}

	prefixFieldClashes(entry.Data)

	isColorTerminal := isTerminal && (runtime.GOOS != "windows")
	isColored := (f.ForceColors || isColorTerminal) && !f.DisableColors

	timestampFormat := f.TimestampFormat
	if timestampFormat == "" {
		timestampFormat = time.Stamp
	}

	if isColored {
		f.printColored(b, entry, keys, timestampFormat)
	} else {
		if !f.DisableTimestamp {
			f.appendKeyValue(b, "time", entry.Time.Format(timestampFormat))
		}
		f.appendKeyValue(b, "level", entry.Level.String())
		if entry.Message != "" {
			f.appendKeyValue(b, "msg", entry.Message)
		}
		for _, key := range keys {
			f.appendKeyValue(b, key, entry.Data[key])
		}
	}

	b.WriteByte('\n')
	return b.Bytes(), nil
}

func (f *TextFormatter) printColored(wr io.Writer, entry *logrus.Entry,
	keys []string, timestampFormat string) {
	var levelColor string
	var levelText string
	var debugInf string
	switch entry.Level {
	case logrus.InfoLevel:
		levelColor = ansi.Green
	case logrus.WarnLevel:
		levelColor = ansi.Yellow
	case logrus.ErrorLevel, logrus.FatalLevel, logrus.PanicLevel:
		levelColor = ansi.Red
	case logrus.DebugLevel:
		pc, file, line, _ := runtime.Caller(6)

		callername := runtime.FuncForPC(pc).Name()
		debugInf = fmt.Sprintf(" [%s][%s][%d]", callername, file, line)
		fallthrough
	default:
		levelColor = ansi.Blue
	}

	if entry.Level != logrus.WarnLevel {
		levelText = strings.ToUpper(entry.Level.String())
	} else {
		levelText = "WARN"
	}

	prefix := ""
	message := entry.Message

	if pfx, ok := entry.Data["prefix"]; ok {
		prefix = fmt.Sprint(" ", ansi.Cyan, pfx, ":", reset)
	} else if pfx, trimmed := extractPrefix(entry.Message); len(pfx) > 0 {
		prefix = fmt.Sprint(" ", ansi.Cyan, pfx, ":", reset)
		message = trimmed
	}

	messageFormat := "%s"
	if f.SpacePadding != 0 {
		messageFormat = fmt.Sprintf("%%-%ds", f.SpacePadding)
	}

	// Remember how many bytes we've written to the buffer (i.e. how long the
	// timestamp, etc. is).
	var padlen int
	if f.DisableTimestamp {
		padlen, _ = fmt.Fprintf(wr, "%s%s %s%+5s%s%s%s ", ansi.LightBlack, reset,
			levelColor, levelText, reset, debugInf, prefix)
	} else {
		if f.ShortTimestamp {
			padlen, _ = fmt.Fprintf(wr, "%s[%04d]%s %s%+5s%s%s%s ",
				ansi.LightBlack, miniTS(), reset, levelColor, levelText, reset,
				debugInf, prefix)
		} else {
			padlen, _ = fmt.Fprintf(wr, "%s[%s]%s %s%+5s%s%s%s ", ansi.LightBlack,
				entry.Time.Format(timestampFormat), reset, levelColor,
				levelText, reset, debugInf, prefix)
		}
	}

	if f.IndentMultilineMessage && strings.ContainsRune(message, '\n') {
		// here we subtract the length of the used control characters
		padlen -= len(ansi.LightBlack) + len(levelColor) + 2*len(reset)
		if prefix != "" {
			padlen -= len(ansi.Cyan) + len(reset)
		}
		fmt.Fprintf(wr, messageFormat, strings.Replace(message, "\n", "\n"+
			strings.Repeat(" ", padlen), -1))
	} else {
		fmt.Fprintf(wr, messageFormat, message)
	}

	for _, k := range keys {
		v := entry.Data[k]
		fmt.Fprintf(wr, " %s%s%s=%+v", levelColor, k, reset, v)
	}
}

func needsQuoting(text string) bool {
	for _, ch := range text {
		if !((ch >= 'a' && ch <= 'z') ||
			(ch >= 'A' && ch <= 'Z') ||
			(ch >= '0' && ch <= '9') ||
			ch == '-' || ch == '.') {
			return false
		}
	}
	return true
}

func extractPrefix(msg string) (string, string) {
	prefix := ""
	regex := regexp.MustCompile(`^\[(.*?)\]`)
	if regex.MatchString(msg) {
		match := regex.FindString(msg)
		prefix, msg = match[1:len(match)-1], strings.TrimSpace(msg[len(match):])
	}
	return prefix, msg
}

func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string,
	value interface{}) {
	b.WriteString(key)
	b.WriteByte('=')

	switch value := value.(type) {
	case string:
		if needsQuoting(value) {
			b.WriteString(value)
		} else {
			fmt.Fprintf(b, "%q", value)
		}
	case error:
		errmsg := value.Error()
		if needsQuoting(errmsg) {
			b.WriteString(errmsg)
		} else {
			fmt.Fprintf(b, "%q", value)
		}
	default:
		fmt.Fprint(b, value)
	}

	b.WriteByte(' ')
}

func prefixFieldClashes(data logrus.Fields) {
	_, ok := data["time"]
	if ok {
		data["fields.time"] = data["time"]
	}
	_, ok = data["msg"]
	if ok {
		data["fields.msg"] = data["msg"]
	}
	_, ok = data["level"]
	if ok {
		data["fields.level"] = data["level"]
	}
}
<|endoftext|>


<commit_before>package api

import (
	"database/sql"
	"encoding/json"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"net/http"
)

type Result struct {
	Spa []Spa `json:"spa"`
}

type Spa struct {
	Id      string `json:"id"`
	Name    string `json:"name"`
	Address string `json:"address"`
}

func ShowSpaList(w http.ResponseWriter, r *http.Request) {
	db, err := sql.Open("mysql", "root:root@/spary")
	//	db, err := sql.Open("mysql", "user:password@/dbname")
	if err != nil {
		panic(err.Error())
	}
	defer db.Close() // 関数がリターンする直前に呼び出される

	rows, err := db.Query("SELECT * FROM spa") //
	if err != nil {
		panic(err.Error())
	}

	columns, err := rows.Columns() // カラム名を取得
	if err != nil {
		panic(err.Error())
	}

	values := make([]sql.RawBytes, len(columns))
	//  rows.Scan は引数に `[]interface{}`が必要.

	scanArgs := make([]interface{}, len(values))
	for i := range values {
		scanArgs[i] = &values[i]
	}

	spaList := []Spa{}
	for rows.Next() {
		spa := Spa{}
		err = rows.Scan(scanArgs...)
		if err != nil {
			panic(err.Error())
		}

		var value string
		for i, col := range values {
			// Here we can check if the value is nil (NULL value)
			if col == nil {
				value = "NULL"
			} else {
				value = string(col)
			}
			if columns[i] == "name" {
				spa.Name = value
				fmt.Printf(value)
			} else if columns[i] == "address" {
				spa.Address = value
				fmt.Printf(value)
			} else if columns[i] == "id" {
				spa.Id = value
				fmt.Printf(value)
			}
		}
		spaList = append(spaList, spa)

	}
	data := Result{}
	data.Spa = spaList
	bytes, err := json.Marshal(data)
	if err != nil {
		return
	}
	fmt.Fprintf(w, "%s\n", string(bytes))
}

func Run() {
	http.HandleFunc("/api/spa/list", ShowSpaList)
	fmt.Printf("Server is running... localhost:8080")
	http.ListenAndServe(":8080", nil)

}
<commit_msg>change user name for mysql<commit_after>package api

import (
	"database/sql"
	"encoding/json"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"net/http"
)

type Result struct {
	Spa []Spa `json:"spa"`
}

type Spa struct {
	Id      string `json:"id"`
	Name    string `json:"name"`
	Address string `json:"address"`
}

func ShowSpaList(w http.ResponseWriter, r *http.Request) {
	db, err := sql.Open("mysql", "spary_admin:spary@YRAPS@/spary")
	//	db, err := sql.Open("mysql", "user:password@/dbname")
	if err != nil {
		panic(err.Error())
	}
	defer db.Close() // 関数がリターンする直前に呼び出される

	rows, err := db.Query("SELECT * FROM spa") //
	if err != nil {
		panic(err.Error())
	}

	columns, err := rows.Columns() // カラム名を取得
	if err != nil {
		panic(err.Error())
	}

	values := make([]sql.RawBytes, len(columns))
	//  rows.Scan は引数に `[]interface{}`が必要.

	scanArgs := make([]interface{}, len(values))
	for i := range values {
		scanArgs[i] = &values[i]
	}

	spaList := []Spa{}
	for rows.Next() {
		spa := Spa{}
		err = rows.Scan(scanArgs...)
		if err != nil {
			panic(err.Error())
		}

		var value string
		for i, col := range values {
			// Here we can check if the value is nil (NULL value)
			if col == nil {
				value = "NULL"
			} else {
				value = string(col)
			}
			if columns[i] == "name" {
				spa.Name = value
				fmt.Printf(value)
			} else if columns[i] == "address" {
				spa.Address = value
				fmt.Printf(value)
			} else if columns[i] == "id" {
				spa.Id = value
				fmt.Printf(value)
			}
		}
		spaList = append(spaList, spa)

	}
	data := Result{}
	data.Spa = spaList
	bytes, err := json.Marshal(data)
	if err != nil {
		return
	}
	fmt.Fprintf(w, "%s\n", string(bytes))
}

func Run() {
	http.HandleFunc("/api/spa/list", ShowSpaList)
	fmt.Printf("Server is running... localhost:8080")
	http.ListenAndServe(":8080", nil)

}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"

	"github.com/PuerkitoBio/goquery"
)

const (
	userAgent   = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36"
	timeLayout  = "02/01/2006"
	storagePath = ".local/share"
)

func main() {
	flag.Parse()

	funds, err := GetFunds(flag.Args()...)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Print(prettyPrint(funds...))
}

func GetFunds(codes ...string) ([]Fund, error) {
	const (
		baseurl = "http://www.akportfoy.com.tr/ajax/getfundreturns?fundsubtypeId=%v&enddate=%v&lang=tr"
	)

	c := &http.Client{Timeout: time.Minute}

	const fund = YabanciHisseSenedi
	today := time.Now().Format(timeLayout)

	u := fmt.Sprintf(baseurl, fund, today)
	req, _ := http.NewRequest("POST", u, nil)
	req.Header.Set("User-Agent", userAgent)

	resp, err := c.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	var response struct {
		Title string
		Table string
	}
	err = json.NewDecoder(resp.Body).Decode(&response)
	if err != nil {
		return nil, err
	}

	doc, err := goquery.NewDocumentFromReader(strings.NewReader(response.Table))
	if err != nil {
		return nil, err
	}

	atof := func(s string) float64 {
		f, _ := strconv.ParseFloat(s, 64)
		return f
	}

	var funds []Fund
	doc.Find("tr").Each(func(i int, sel *goquery.Selection) {
		if i == 0 {
			return
		}

		code := sel.Find(".fundcode").Text()
		name := sel.Find("th").Text()
		name = strings.TrimPrefix(name, code)
		name = strings.TrimSpace(name)

		if len(codes) != 0 {
			var found bool
			for _, c := range codes {
				if strings.ToLower(c) == strings.ToLower(code) {
					found = true
					break
				}
			}
			if !found {
				return
			}
		}

		fund := Fund{
			Code: code,
			Name: name,
		}

		sel.Children().Each(func(n int, sel *goquery.Selection) {
			switch n {
			case 1:
				fund.Price = atof(sel.Text())
			case 2:
				fund.Daily = atof(sel.Text())
			case 3:
				fund.Weekly = atof(sel.Text())
			case 4:
				fund.Monthly = atof(sel.Text())
			case 5:
				fund.Annual = atof(sel.Text())
			}
		})

		funds = append(funds, fund)
	})

	return funds, nil
}

type Fund struct {
	Type    FundType
	Code    string
	Name    string
	Price   float64
	Daily   float64
	Weekly  float64
	Monthly float64
	Annual  float64
}

type FundType uint8

const (
	ParaPiyasasi            FundType = 5
	BorclanmaAraclari       FundType = 6
	Katilim                 FundType = 4
	Degisken                FundType = 2
	HisseSenedi             FundType = 1
	YabanciHisseSenedi      FundType = 7
	DegerliMaden            FundType = 3
	FonSepeti               FundType = 9
	GayrimenkulYatirim      FundType = 32
	GirisimSermayesiYatirim FundType = 30
	DovizSerbest            FundType = 71
)

func prettyPrint(funds ...Fund) string {
	color := func(f float64) string {
		switch {
		case f == 0:
			return "grey"
		case f < 0:
			return "red"
		case f > 0:
			return "green"
		}
		return "black"
	}

	var buf bytes.Buffer

	header := "%v (%v) \x1b[31;1;8m%v\x1b[0m | size=13 href=http://www.tefas.gov.tr/FonAnaliz.aspx?FonKod=%v\n"

	for _, f := range funds {
		sethop(f.Code, time.Now(), f.Daily)

		// calculate the fall
		hop := gethop(f.Code)
		var freefall string
		for _, h := range hop {
			if h.DailyChange < 0 {
				freefall += "◉ "
			} else {
				freefall = ""
			}
		}

		name := strings.TrimPrefix(f.Name, "Ak Portföy ")
		name = strings.TrimSuffix(name, "Yabancı Hisse Senedi Fonu")
		name = strings.TrimSpace(name)

		fmt.Fprintf(&buf, header, f.Code, name, freefall, f.Code)
		fmt.Fprintf(&buf, "• Fiyat:  %v | color=%v size=11\n", f.Price, "black")
		fmt.Fprintf(&buf, "• Günlük:  %v%% | color=%v size=11\n", f.Daily, color(f.Daily))
		fmt.Fprintf(&buf, "• Haftalık:  %v%% | color=%v size=11\n", f.Weekly, color(f.Weekly))
		fmt.Fprintf(&buf, "• Aylık: %v%% | color=%v size=11\n", f.Monthly, color(f.Monthly))
		fmt.Fprintf(&buf, "• Yıllık:  %v%% | color=%v size=11\n", f.Annual, color(f.Annual))
		fmt.Fprintf(&buf, "---\n")
	}
	return buf.String()
}

func sethop(code string, date time.Time, change float64) {
	home := os.Getenv("HOME")
	path := filepath.Join(home, storagePath)
	os.MkdirAll(path, 0755)
	fpath := filepath.Join(path, "funds.json")

	_, err := os.Stat(fpath)
	if os.IsNotExist(err) {
		ioutil.WriteFile(fpath, []byte("{}"), 0644)
	}

	allhops := gethops()

	datestr := date.Format(timeLayout)
	hop := Hop{Date: datestr, DailyChange: change}

	hops, ok := allhops[code]
	if !ok {
		hops = []Hop{hop}
	} else {
		var found bool
		for _, h := range hops {
			if h.Date == datestr {
				found = true
				break
			}
		}
		if !found {
			hops = append(hops, hop)
		}
	}

	// limit the size of the slice to 3
	if len(hops) >= 3 {
		hops = hops[len(hops)-3 : len(hops)]
	}

	allhops[code] = hops

	b, _ := json.Marshal(allhops)
	_ = ioutil.WriteFile(fpath, b, 0644)
}

func gethops() map[string][]Hop {
	home := os.Getenv("HOME")
	path := filepath.Join(home, storagePath)
	os.MkdirAll(path, 0755)
	fpath := filepath.Join(path, "funds.json")

	m := make(map[string][]Hop)

	content, _ := ioutil.ReadFile(fpath)
	_ = json.Unmarshal(content, &m)

	return m
}

func gethop(code string) []Hop {
	all := gethops()
	v, _ := all[code]
	return v
}

type Hop struct {
	Date        string
	DailyChange float64
}
<commit_msg>fund: a couple of fixes<commit_after>package main

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"

	"github.com/PuerkitoBio/goquery"
)

const (
	userAgent   = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36"
	timeLayout  = "02/01/2006"
	storagePath = ".local/share"
)

var (
	ErrDisabled = fmt.Errorf("disabled on weekends")
)

func main() {
	flag.Parse()

	funds, err := GetFunds(flag.Args()...)
	switch err {
	case ErrDisabled:
		fmt.Println(err)
		os.Exit(0)
	default:
		log.Fatal(err)
	}

	fmt.Print(prettyPrint(funds...))
}

func GetFunds(codes ...string) ([]Fund, error) {
	const (
		baseurl = "http://www.akportfoy.com.tr/ajax/getfundreturns?fundsubtypeId=%v&enddate=%v&lang=tr"
	)

	c := &http.Client{Timeout: time.Minute}

	const fund = YabanciHisseSenedi
	today := time.Now()

	switch today.Weekday() {
	case 6, 0: // saturday and sunday
		return nil, ErrDisabled
	}

	u := fmt.Sprintf(baseurl, fund, today.Format(timeLayout))
	req, _ := http.NewRequest("POST", u, nil)
	req.Header.Set("User-Agent", userAgent)

	resp, err := c.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	var response struct {
		Title string
		Table string
	}

	if err := json.NewDecoder(resp.Body).Decode(&response); err != nil {
		return nil, err
	}

	doc, err := goquery.NewDocumentFromReader(strings.NewReader(response.Table))
	if err != nil {
		return nil, err
	}

	atof := func(s string) float64 {
		f, _ := strconv.ParseFloat(s, 64)
		return f
	}

	var funds []Fund
	doc.Find("tr").Each(func(i int, sel *goquery.Selection) {
		if i == 0 {
			return
		}

		code := sel.Find(".fundcode").Text()
		name := sel.Find("th").Text()
		name = strings.TrimPrefix(name, code)
		name = strings.TrimSpace(name)

		if len(codes) != 0 {
			var found bool
			for _, c := range codes {
				if strings.ToLower(c) == strings.ToLower(code) {
					found = true
					break
				}
			}
			if !found {
				return
			}
		}

		fund := Fund{
			Code: code,
			Name: name,
		}

		sel.Children().Each(func(n int, sel *goquery.Selection) {
			switch n {
			case 1:
				fund.Price = atof(sel.Text())
			case 2:
				fund.Daily = atof(sel.Text())
			case 3:
				fund.Weekly = atof(sel.Text())
			case 4:
				fund.Monthly = atof(sel.Text())
			case 5:
				fund.Annual = atof(sel.Text())
			}
		})

		funds = append(funds, fund)
	})

	return funds, nil
}

type Fund struct {
	Type    FundType
	Code    string
	Name    string
	Price   float64
	Daily   float64
	Weekly  float64
	Monthly float64
	Annual  float64
}

type FundType uint8

const (
	ParaPiyasasi            FundType = 5
	BorclanmaAraclari       FundType = 6
	Katilim                 FundType = 4
	Degisken                FundType = 2
	HisseSenedi             FundType = 1
	YabanciHisseSenedi      FundType = 7
	DegerliMaden            FundType = 3
	FonSepeti               FundType = 9
	GayrimenkulYatirim      FundType = 32
	GirisimSermayesiYatirim FundType = 30
	DovizSerbest            FundType = 71
)

func prettyPrint(funds ...Fund) string {
	color := func(f float64) string {
		switch {
		case f == 0:
			return "grey"
		case f < 0:
			return "red"
		case f > 0:
			return "green"
		}
		return "black"
	}

	var buf bytes.Buffer

	header := "%v (%v) \x1b[31;1;8m%v\x1b[0m | size=13 href=http://www.tefas.gov.tr/FonAnaliz.aspx?FonKod=%v\n"

	for _, f := range funds {
		sethop(f.Code, time.Now(), f.Daily)

		// calculate the fall
		hop := gethop(f.Code)
		var freefall string
		for _, h := range hop {
			if h.DailyChange < 0 {
				freefall += "◉ "
			} else {
				freefall = ""
			}
		}

		name := strings.TrimPrefix(f.Name, "Ak Portföy ")
		name = strings.TrimSuffix(name, "Yabancı Hisse Senedi Fonu")
		name = strings.TrimSpace(name)

		fmt.Fprintf(&buf, header, f.Code, name, freefall, f.Code)
		fmt.Fprintf(&buf, "• Fiyat:  %v | color=%v size=11\n", f.Price, "black")
		fmt.Fprintf(&buf, "• Günlük:  %v%% | color=%v size=11\n", f.Daily, color(f.Daily))
		fmt.Fprintf(&buf, "• Haftalık:  %v%% | color=%v size=11\n", f.Weekly, color(f.Weekly))
		fmt.Fprintf(&buf, "• Aylık: %v%% | color=%v size=11\n", f.Monthly, color(f.Monthly))
		fmt.Fprintf(&buf, "• Yıllık:  %v%% | color=%v size=11\n", f.Annual, color(f.Annual))
		fmt.Fprintf(&buf, "---\n")
	}
	return buf.String()
}

func sethop(code string, date time.Time, change float64) {
	home := os.Getenv("HOME")
	path := filepath.Join(home, storagePath)
	os.MkdirAll(path, 0755)
	fpath := filepath.Join(path, "funds.json")

	_, err := os.Stat(fpath)
	if os.IsNotExist(err) {
		ioutil.WriteFile(fpath, []byte("{}"), 0644)
	}

	allhops := gethops()

	datestr := date.Format(timeLayout)
	hop := Hop{Date: datestr, DailyChange: change}

	hops, ok := allhops[code]
	if !ok {
		hops = []Hop{hop}
	} else {
		var found bool
		for _, h := range hops {
			if h.Date == datestr {
				found = true
				break
			}
		}
		if !found {
			hops = append(hops, hop)
		}
	}

	// limit the size of the slice to 3
	if len(hops) >= 3 {
		hops = hops[len(hops)-3 : len(hops)]
	}

	allhops[code] = hops

	b, _ := json.Marshal(allhops)
	_ = ioutil.WriteFile(fpath, b, 0644)
}

func gethops() map[string][]Hop {
	home := os.Getenv("HOME")
	path := filepath.Join(home, storagePath)
	os.MkdirAll(path, 0755)
	fpath := filepath.Join(path, "funds.json")

	m := make(map[string][]Hop)

	content, _ := ioutil.ReadFile(fpath)
	_ = json.Unmarshal(content, &m)

	return m
}

func gethop(code string) []Hop {
	all := gethops()
	v, _ := all[code]
	return v
}

type Hop struct {
	Date        string
	DailyChange float64
}
<|endoftext|>


<commit_before>// Copyright 2016 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package logging_test

import (
	"context"
	"encoding/json"
	"fmt"
	"os"

	"cloud.google.com/go/logging"
	"go.opencensus.io/trace"
)

func ExampleNewClient() {
	ctx := context.Background()
	client, err := logging.NewClient(ctx, "my-project")
	if err != nil {
		// TODO: Handle error.
	}
	// Use client to manage logs, metrics and sinks.
	// Close the client when finished.
	if err := client.Close(); err != nil {
		// TODO: Handle error.
	}
}

func ExampleClient_Ping() {
	ctx := context.Background()
	client, err := logging.NewClient(ctx, "my-project")
	if err != nil {
		// TODO: Handle error.
	}
	if err := client.Ping(ctx); err != nil {
		// TODO: Handle error.
	}
}

// Although Logger.Flush and Client.Close both return errors, they don't tell you
// whether the errors were frequent or significant. For most programs, it doesn't
// matter if there were a few errors while writing logs, although if those few errors
// indicated a bug in your program, you might want to know about them. The best way
// to handle errors is by setting the OnError function. If it runs quickly, it will
// see every error generated during logging.
func ExampleNewClient_errorFunc() {
	ctx := context.Background()
	client, err := logging.NewClient(ctx, "my-project")
	if err != nil {
		// TODO: Handle error.
	}
	// Print all errors to stdout, and count them. Multiple calls to the OnError
	// function never happen concurrently, so there is no need for locking nErrs,
	// provided you don't read it until after the logging client is closed.
	var nErrs int
	client.OnError = func(e error) {
		fmt.Fprintf(os.Stdout, "logging: %v", e)
		nErrs++
	}
	// Use client to manage logs, metrics and sinks.
	// Close the client when finished.
	if err := client.Close(); err != nil {
		// TODO: Handle error.
	}
	fmt.Printf("saw %d errors\n", nErrs)
}

func ExampleClient_Logger() {
	ctx := context.Background()
	client, err := logging.NewClient(ctx, "my-project")
	if err != nil {
		// TODO: Handle error.
	}
	lg := client.Logger("my-log")
	_ = lg // TODO: use the Logger.
}

func ExampleLogger_LogSync() {
	ctx := context.Background()
	client, err := logging.NewClient(ctx, "my-project")
	if err != nil {
		// TODO: Handle error.
	}
	lg := client.Logger("my-log")
	err = lg.LogSync(ctx, logging.Entry{Payload: "red alert"})
	if err != nil {
		// TODO: Handle error.
	}
}

func ExampleLogger_Log() {
	ctx := context.Background()
	client, err := logging.NewClient(ctx, "my-project")
	if err != nil {
		// TODO: Handle error.
	}
	lg := client.Logger("my-log")
	lg.Log(logging.Entry{Payload: "something happened"})
}

// An Entry payload can be anything that marshals to a
// JSON object, like a struct.
func ExampleLogger_Log_struct() {
	type MyEntry struct {
		Name  string
		Count int
	}

	ctx := context.Background()
	client, err := logging.NewClient(ctx, "my-project")
	if err != nil {
		// TODO: Handle error.
	}
	lg := client.Logger("my-log")
	lg.Log(logging.Entry{Payload: MyEntry{Name: "Bob", Count: 3}})
}

// To log a JSON value, wrap it in json.RawMessage.
func ExampleLogger_Log_json() {
	ctx := context.Background()
	client, err := logging.NewClient(ctx, "my-project")
	if err != nil {
		// TODO: Handle error.
	}
	lg := client.Logger("my-log")
	j := []byte(`{"Name": "Bob", "Count": 3}`)
	lg.Log(logging.Entry{Payload: json.RawMessage(j)})
}

func ExampleLogger_Flush() {
	ctx := context.Background()
	client, err := logging.NewClient(ctx, "my-project")
	if err != nil {
		// TODO: Handle error.
	}
	lg := client.Logger("my-log")
	lg.Log(logging.Entry{Payload: "something happened"})
	lg.Flush()
}

func ExampleLogger_StandardLogger() {
	ctx := context.Background()
	client, err := logging.NewClient(ctx, "my-project")
	if err != nil {
		// TODO: Handle error.
	}
	lg := client.Logger("my-log")
	slg := lg.StandardLogger(logging.Info)
	slg.Println("an informative message")
}

func ExampleParseSeverity() {
	sev := logging.ParseSeverity("ALERT")
	fmt.Println(sev)
	// Output: Alert
}

// This example shows how to create a Logger that disables OpenCensus tracing of the
// WriteLogEntries RPC.
func ExampleContextFunc() {
	ctx := context.Background()
	client, err := logging.NewClient(ctx, "my-project")
	if err != nil {
		// TODO: Handle error.
	}
	lg := client.Logger("logID", logging.ContextFunc(func() (context.Context, func()) {
		ctx, span := trace.StartSpan(context.Background(), "this span will not be exported",
			trace.WithSampler(trace.NeverSample()))
		return ctx, span.End
	}))
	_ = lg // TODO: Use lg
}
<commit_msg>docs(logging): add example for logging the HTTPRequest type (#3097)<commit_after>// Copyright 2016 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package logging_test

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"os"

	"cloud.google.com/go/logging"
	"go.opencensus.io/trace"
)

func ExampleNewClient() {
	ctx := context.Background()
	client, err := logging.NewClient(ctx, "my-project")
	if err != nil {
		// TODO: Handle error.
	}
	// Use client to manage logs, metrics and sinks.
	// Close the client when finished.
	if err := client.Close(); err != nil {
		// TODO: Handle error.
	}
}

func ExampleClient_Ping() {
	ctx := context.Background()
	client, err := logging.NewClient(ctx, "my-project")
	if err != nil {
		// TODO: Handle error.
	}
	if err := client.Ping(ctx); err != nil {
		// TODO: Handle error.
	}
}

// Although Logger.Flush and Client.Close both return errors, they don't tell you
// whether the errors were frequent or significant. For most programs, it doesn't
// matter if there were a few errors while writing logs, although if those few errors
// indicated a bug in your program, you might want to know about them. The best way
// to handle errors is by setting the OnError function. If it runs quickly, it will
// see every error generated during logging.
func ExampleNewClient_errorFunc() {
	ctx := context.Background()
	client, err := logging.NewClient(ctx, "my-project")
	if err != nil {
		// TODO: Handle error.
	}
	// Print all errors to stdout, and count them. Multiple calls to the OnError
	// function never happen concurrently, so there is no need for locking nErrs,
	// provided you don't read it until after the logging client is closed.
	var nErrs int
	client.OnError = func(e error) {
		fmt.Fprintf(os.Stdout, "logging: %v", e)
		nErrs++
	}
	// Use client to manage logs, metrics and sinks.
	// Close the client when finished.
	if err := client.Close(); err != nil {
		// TODO: Handle error.
	}
	fmt.Printf("saw %d errors\n", nErrs)
}

func ExampleClient_Logger() {
	ctx := context.Background()
	client, err := logging.NewClient(ctx, "my-project")
	if err != nil {
		// TODO: Handle error.
	}
	lg := client.Logger("my-log")
	_ = lg // TODO: use the Logger.
}

func ExampleHTTPRequest() {
	ctx := context.Background()
	client, err := logging.NewClient(ctx, "my-project")
	if err != nil {
		// TODO: Handle error.
	}
	lg := client.Logger("my-log")
	httpEntry := logging.Entry{
		Payload: "optional message",
		HTTPRequest: &logging.HTTPRequest{
			// TODO: pass in request
			Request: &http.Request{},
		},
	}
	lg.Log(httpEntry)
}

func ExampleLogger_LogSync() {
	ctx := context.Background()
	client, err := logging.NewClient(ctx, "my-project")
	if err != nil {
		// TODO: Handle error.
	}
	lg := client.Logger("my-log")
	err = lg.LogSync(ctx, logging.Entry{Payload: "red alert"})
	if err != nil {
		// TODO: Handle error.
	}
}

func ExampleLogger_Log() {
	ctx := context.Background()
	client, err := logging.NewClient(ctx, "my-project")
	if err != nil {
		// TODO: Handle error.
	}
	lg := client.Logger("my-log")
	lg.Log(logging.Entry{Payload: "something happened"})
}

// An Entry payload can be anything that marshals to a
// JSON object, like a struct.
func ExampleLogger_Log_struct() {
	type MyEntry struct {
		Name  string
		Count int
	}

	ctx := context.Background()
	client, err := logging.NewClient(ctx, "my-project")
	if err != nil {
		// TODO: Handle error.
	}
	lg := client.Logger("my-log")
	lg.Log(logging.Entry{Payload: MyEntry{Name: "Bob", Count: 3}})
}

// To log a JSON value, wrap it in json.RawMessage.
func ExampleLogger_Log_json() {
	ctx := context.Background()
	client, err := logging.NewClient(ctx, "my-project")
	if err != nil {
		// TODO: Handle error.
	}
	lg := client.Logger("my-log")
	j := []byte(`{"Name": "Bob", "Count": 3}`)
	lg.Log(logging.Entry{Payload: json.RawMessage(j)})
}

func ExampleLogger_Flush() {
	ctx := context.Background()
	client, err := logging.NewClient(ctx, "my-project")
	if err != nil {
		// TODO: Handle error.
	}
	lg := client.Logger("my-log")
	lg.Log(logging.Entry{Payload: "something happened"})
	lg.Flush()
}

func ExampleLogger_StandardLogger() {
	ctx := context.Background()
	client, err := logging.NewClient(ctx, "my-project")
	if err != nil {
		// TODO: Handle error.
	}
	lg := client.Logger("my-log")
	slg := lg.StandardLogger(logging.Info)
	slg.Println("an informative message")
}

func ExampleParseSeverity() {
	sev := logging.ParseSeverity("ALERT")
	fmt.Println(sev)
	// Output: Alert
}

// This example shows how to create a Logger that disables OpenCensus tracing of the
// WriteLogEntries RPC.
func ExampleContextFunc() {
	ctx := context.Background()
	client, err := logging.NewClient(ctx, "my-project")
	if err != nil {
		// TODO: Handle error.
	}
	lg := client.Logger("logID", logging.ContextFunc(func() (context.Context, func()) {
		ctx, span := trace.StartSpan(context.Background(), "this span will not be exported",
			trace.WithSampler(trace.NeverSample()))
		return ctx, span.End
	}))
	_ = lg // TODO: Use lg
}
<|endoftext|>