Skip to content

Commit

Permalink
Merge pull request getlantern#2956 from getlantern/issue-2252
Browse files Browse the repository at this point in the history
Include OS version in Loggly messages
  • Loading branch information
myleshorton committed Aug 18, 2015
2 parents 8d05f65 + 19bb14f commit f39c248
Show file tree
Hide file tree
Showing 269 changed files with 107,200 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/github.com/getlantern/flashlight/logging/logging.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/getlantern/go-loggly"
"github.com/getlantern/golog"
"github.com/getlantern/jibber_jabber"
"github.com/getlantern/osversion"
"github.com/getlantern/rotator"
"github.com/getlantern/wfilter"
)
Expand Down Expand Up @@ -162,6 +163,9 @@ func enableLoggly(addr string, cloudConfigCA string, instanceId string,
}
logglyWriter.client.Defaults["hostname"] = "hidden"
logglyWriter.client.Defaults["instanceid"] = instanceId
if osStr, err := osversion.GetHumanReadable(); err == nil {
logglyWriter.client.Defaults["osversion"] = osStr
}
logglyWriter.client.SetHTTPClient(client)
addLoggly(logglyWriter)
}
Expand Down
1 change: 1 addition & 0 deletions src/github.com/getlantern/osversion/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Go library for OS version discovery
9 changes: 9 additions & 0 deletions src/github.com/getlantern/osversion/cmd/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
linux:
CGO_ENABLED=1 GOOS=linux GOARCH=386 go run /src/github.com/getlantern/osversion/cmd

windows:
CGO_ENABLED=1 GOOS=windows GOARCH=386 go run /src/github.com/getlantern/osversion/cmd

android:
GOOS=android GOARCH=arm gomobile build -target=android github.com/getlantern/osversion/cmd && \
adb install -r cmd.apk
31 changes: 31 additions & 0 deletions src/github.com/getlantern/osversion/cmd/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// +build !android

package main

import (
"log"

"github.com/getlantern/osversion"
)

func main() {
str, err := osversion.GetString()
if err != nil {
log.Fatalf("Error getting OS version: %v", err)
}
log.Println(str)

version, err := osversion.GetSemanticVersion()
if err != nil {
log.Fatalf("Error getting OS version: %v", err)
}

log.Println(version)

hstr, err := osversion.GetHumanReadable()
if err != nil {
log.Fatalf("Error getting OS version: %v", err)
}

log.Println(hstr)
}
32 changes: 32 additions & 0 deletions src/github.com/getlantern/osversion/cmd/main_android.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package main

import (
"log"

"github.com/getlantern/osversion"

"golang.org/x/mobile/app"
)

func main() {
// checkNetwork runs only once when the app first loads.
app.Main(func(a app.App) {
str, err := osversion.GetString()
if err != nil {
log.Printf("Error in osversion.GetString: %v", err)
}
log.Println(str)

semVer, err := osversion.GetSemanticVersion()
if err != nil {
log.Printf("Error in osversion.GetSemanticVersion: %v", err)
}
log.Println(semVer.String())

str, err = osversion.GetHumanReadable()
if err != nil {
log.Printf("Error in osversion.GetHumanReadable: %v", err)
}
log.Println(str)
})
}
14 changes: 14 additions & 0 deletions src/github.com/getlantern/osversion/osversion.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package osversion

import (
"github.com/blang/semver"
)

func GetSemanticVersion() (semver.Version, error) {
str, err := GetString()
if err != nil {
return semver.Version{}, err
}

return semver.Make(str)
}
87 changes: 87 additions & 0 deletions src/github.com/getlantern/osversion/osversion_android.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package osversion

/*
#include <sys/system_properties.h>
#include <stdio.h>
#include <stdlib.h>
int android_get_prop_value_max() {
return PROP_VALUE_MAX;
}
int android_get_release(char *sdk_ver_str) {
int result = __system_property_get("ro.build.version.release", sdk_ver_str);
return result;
}
int android_get_api(char *sdk_ver_str) {
int result = __system_property_get("ro.build.version.sdk", sdk_ver_str);
return result;
}
*/
import "C"

import (
"errors"
"fmt"
"strconv"
"unsafe"
)

func GetString() (string, error) {
strSize := int(C.android_get_prop_value_max())
verStr := (*C.char)(C.malloc(C.size_t(strSize)))
defer C.free(unsafe.Pointer(verStr))
C.android_get_release(verStr)
return C.GoString(verStr), nil
}

func GetHumanReadable() (string, error) {
// First get the semantic versioning scheme
verStr, err := GetString()
if err != nil {
return verStr, err
}

// Then get the release name
strSize := int(C.android_get_prop_value_max())
apiStr := (*C.char)(C.malloc(C.size_t(strSize)))
defer C.free(unsafe.Pointer(apiStr))
C.android_get_api(apiStr)

i, err := strconv.ParseUint(C.GoString(apiStr), 10, 16)
if err != nil {
return verStr, err
}

if i > 22 {
return verStr, errors.New("Unknown Android API version")
}

return fmt.Sprintf("%s %s", versions[i-1], verStr), nil
}

var versions = []string{
"", // 1
"", // 2
"Cupcake", // 3
"Donut", // 4
"Eclair", // 5
"Eclair", // 6
"Eclair", // 7
"Froyo", // 8
"Gingerbread", // 9
"Gingerbread", // 10
"Honeycomb", // 11
"Honeycomb", // 12
"Honeycomb", // 13
"Ice Cream Sandwhich", // 14
"Ice Cream Sandwhich", // 15
"Jelly Bean", // 16
"Jelly Bean", // 17
"Jelly Bean", // 18
"KitKat", // 19
"KitKat", // 20
"Lollipop", // 21
"Lollipop", // 22
}
64 changes: 64 additions & 0 deletions src/github.com/getlantern/osversion/osversion_darwin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package osversion

/*
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/sysctl.h>
int darwin_get_os(char* str, size_t size) {
return sysctlbyname("kern.osrelease", str, &size, NULL, 0);
}
*/
import "C"

import (
"errors"
"fmt"
"strconv"
"strings"
"unsafe"
)

func GetString() (string, error) {
bufferSize := C.size_t(256)
str := (*C.char)(C.malloc(bufferSize))
defer C.free(unsafe.Pointer(str))

err := C.darwin_get_os(str, bufferSize)
if err == -1 {
return "", errors.New(fmt.Sprintf("Error running sysctl: %v", err))
}
return C.GoString(str), nil
}

func GetHumanReadable() (string, error) {
version, err := GetSemanticVersion()
if err != nil {
return "", err
}
if version.Major < 4 || version.Major > 15 {
return fmt.Sprintf("Unknown OS X version: %s", version.String()), nil
}

return strings.Replace(versions[version.Major-4],
"{patch}",
strconv.FormatUint(version.Patch, 10),
1), nil
}

var versions = []string{
"OS X 10.0.{patch} Cheetah",
"OS X 10.1.{patch} Puma",
"OS X 10.2.{patch} Jaguar",
"OS X 10.3.{patch} Panther",
"OS X 10.4.{patch} Tiger",
"OS X 10.5.{patch} Leopard",
"OS X 10.6.{patch} Snow Leopard",
"OS X 10.7.{patch} Lion",
"OS X 10.8.{patch} Mountain Lion",
"OS X 10.9.{patch} Mavericks",
"OS X 10.10.{patch} Yosemite",
"OS X 10.11.{patch} El Capitan",
}
57 changes: 57 additions & 0 deletions src/github.com/getlantern/osversion/osversion_linux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// +build !android

package osversion

import (
"C"
"errors"
"fmt"
"io/ioutil"
"regexp"
"syscall"
)

func GetString() (string, error) {
var uts syscall.Utsname
err := syscall.Uname(&uts)
if err != nil {
return "", errors.New(fmt.Sprintf("Error calling system function 'uname': %s", err))
}
return fmt.Sprintf("%s", int8SliceToString(uts.Release[:])), nil
}

func GetHumanReadable() (string, error) {
// Kernel version
kernel, err := GetString()
if err != nil {
return "", err
}

// Try to get the distribution info
fData, err := ioutil.ReadFile("/etc/os-release")
if err != nil {
return fmt.Sprintf("kernel: %s", kernel), nil
}

// At least Fedora, Debian, Ubuntu and Arch support this approach
// and provide the PRETTY_NAME field
reg1 := regexp.MustCompile("PRETTY_NAME=\".+\"")
reg2 := regexp.MustCompile("\".+\"")
dstrBytes := reg2.Find(reg1.Find(fData))
distribution := string(dstrBytes[1 : len(dstrBytes)-1])

return fmt.Sprintf("%s kernel: %s", distribution, kernel), nil
}

func int8SliceToString(ca []int8) string {
s := make([]byte, len(ca))
strpos := 0
for strpos < len(ca) {
if ca[strpos] == 0 {
break
}
s[strpos] = uint8(ca[strpos])
strpos++
}
return string(s[:strpos])
}
52 changes: 52 additions & 0 deletions src/github.com/getlantern/osversion/osversion_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package osversion

import (
"regexp"
"runtime"
"testing"
)

func TestString(t *testing.T) {
reg := regexp.MustCompile("^([0-9])+\\.([0-9])+\\.([0-9])+.*")
str, err := GetString()
if err != nil {
t.Fatal("Error getting string")
}
if !reg.MatchString(str) {
t.Fatalf("Improper string format: %s", str)
}
}

func TestHumanReadable(t *testing.T) {
switch runtime.GOOS {
case "darwin":
str, err := GetHumanReadable()
if err != nil {
t.Fatal("Error getting string")
}
reg := regexp.MustCompile("OS X 10\\..+")
if !reg.MatchString(str) {
t.Fatalf("Improper human readable format: %s", str)
}
case "linux":
str, err := GetHumanReadable()
if err != nil {
t.Fatal("Error getting string")
}
reg := regexp.MustCompile(".*kernel.+")
if !reg.MatchString(str) {
t.Fatalf("Improper human readable format: %s", str)
}
case "windows":
str, err := GetHumanReadable()
if err != nil {
t.Fatal("Error getting string")
}
reg := regexp.MustCompile("Windows .+")
if !reg.MatchString(str) {
t.Fatalf("Improper human readable format: %s", str)
}
default:
t.Fatal("Unsupported OS detected: %s", runtime.GOOS)
}
}
Loading

0 comments on commit f39c248

Please sign in to comment.