func (w logglyErrorWriter) Write(b []byte) (int, error) { extra := map[string]string{ "logLevel": "ERROR", "osName": runtime.GOOS, "osArch": runtime.GOARCH, "osVersion": "", "language": w.lang, "country": geolookup.GetCountry(), "timeZone": w.tz, "version": w.versionToLoggly, } fullMessage := string(b) // extract last 2 (at most) chunks of fullMessage to message, without prefix, // so we can group logs with same reason in Loggly lastColonPos := -1 colonsSeen := 0 for p := len(fullMessage) - 2; p >= 0; p-- { if fullMessage[p] == ':' { lastChar := fullMessage[p+1] // to prevent colon in "http://" and "x.x.x.x:80" be treated as seperator if !(lastChar == '/' || lastChar >= '0' && lastChar <= '9') { lastColonPos = p colonsSeen++ if colonsSeen == 2 { break } } } } message := strings.TrimSpace(fullMessage[lastColonPos+1:]) // Loggly doesn't group fields with more than 100 characters if len(message) > 100 { message = message[0:100] } firstColonPos := strings.IndexRune(fullMessage, ':') if firstColonPos == -1 { firstColonPos = 0 } prefix := fullMessage[0:firstColonPos] m := loggly.Message{ "extra": extra, "locationInfo": prefix, "message": message, "fullMessage": fullMessage, } err := w.client.Send(m) if err != nil { return 0, err } return len(b), nil }
// recordTimings records timing information for the given step in establishing // a connection. It always records that the step happened, and it records the // highest timing threshold exceeded by the step. Thresholds are 1, 2, 4, 8, // and 16 seconds. // // For example, if calling this with step = "DNSLookup" and duration = 2.5 // seconds, we will increment two gauges, "DNSLookup" and // "DNSLookupOver2Sec". // // The stats are qualified by MasqueradeSet (if specified), otherwise they're // qualified by host. For example, if the MasqueradeSet is "cloudflare", the // above stats would be recorded as "DNSLookupTocloudflare" and // "DNSLookupTocloudflareOver2Sec". If the MasqueradeSet is "" and the host is // "localhost", the stats would be recorded as "DNSLookupTolocalhost" and // "DNSLookupTolocalhostOver2Sec". func (s *FrontedServerInfo) recordTiming(step string, duration time.Duration) { if s.MasqueradeSet != "" { step = fmt.Sprintf("%sTo%s", step, s.MasqueradeSet) } else { step = fmt.Sprintf("%sTo%s", step, s.Host) } dims := statreporter.Dim("country", geolookup.GetCountry()) dims.Gauge(step).Add(1) for i := 4; i >= 0; i-- { seconds := int(math.Pow(float64(2), float64(i))) if duration > time.Duration(seconds)*time.Second { key := fmt.Sprintf("%sOver%dSec", step, seconds) dims.Gauge(key).Add(1) return } } }
func (dg *DimGroup) WithCountry() *DimGroup { return dg.And(countryDim, geolookup.GetCountry()) }
func CountryDim() *DimGroup { return Country(geolookup.GetCountry()) }