Skip to content

Commit

Permalink
feat(logging): switch to zerolog for logging
Browse files Browse the repository at this point in the history
  • Loading branch information
joshuar committed May 1, 2023
1 parent 2c5776a commit 42ecac3
Show file tree
Hide file tree
Showing 10 changed files with 177 additions and 35 deletions.
28 changes: 28 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Ignore everything
*

# But not these files...
!/.gitignore

!*.go
!translations/**/*.json
!*.yml
!*.yaml
!go.sum
!go.mod

!README.md
!LICENSE
!CHANGELOG.md
!assets/
!docs/**/*.md
!docs/**/*.png
!tools/

# !Makefile

# ...even if they are in subdirectories
!*/
.vscode/settings.json

dist/
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
<!--
Copyright (c) 2023 Joshua Rich <joshua.rich@gmail.com>
This software is released under the MIT License.
https://opensource.org/licenses/MIT
-->

# gokbd

[![gokbd](https://goreportcard.com/badge/github.com/joshuar/gokbd?style=flat-square)](https://goreportcard.com/report/github.com/joshuar/gokbd)
Expand Down
21 changes: 16 additions & 5 deletions examples/snoop/main.go
Original file line number Diff line number Diff line change
@@ -1,23 +1,34 @@
// Copyright (c) 2023 Joshua Rich <joshua.rich@gmail.com>
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT

package main

import (
"os"

gokbd "github.com/joshuar/gokbd"
log "github.com/sirupsen/logrus"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/rs/zerolog/pkgerrors"
)

func main() {
log.SetLevel(log.DebugLevel)
zerolog.ErrorStackMarshaler = pkgerrors.MarshalStack
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
zerolog.SetGlobalLevel(zerolog.DebugLevel)

keys := gokbd.SnoopAllKeyboards(gokbd.OpenKeyboardDevices())
for k := range keys {
if k.Value == 1 && k.TypeName == "EV_KEY" {
log.Infof("Key pressed: %s %s %d %c\n", k.TypeName, k.EventName, k.Value, k.AsRune)
log.Debug().Msgf("Key pressed: %s %s %d %c\n", k.TypeName, k.EventName, k.Value, k.AsRune)
}
if k.Value == 0 && k.TypeName == "EV_KEY" {
log.Infof("Key released: %s %s %d\n", k.TypeName, k.EventName, k.Value)
log.Debug().Msgf("Key released: %s %s %d\n", k.TypeName, k.EventName, k.Value)
}
if k.Value == 2 && k.TypeName == "EV_KEY" {
log.Infof("Key held: %s %s %d %c\n", k.TypeName, k.EventName, k.Value, k.AsRune)
log.Debug().Msgf("Key held: %s %s %d %c\n", k.TypeName, k.EventName, k.Value, k.AsRune)
}
}
}
16 changes: 14 additions & 2 deletions examples/type/main.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
// Copyright (c) 2023 Joshua Rich <joshua.rich@gmail.com>
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT

package main

import (
"os"

"github.com/joshuar/gokbd"
log "github.com/sirupsen/logrus"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/rs/zerolog/pkgerrors"
)

func main() {
log.SetLevel(log.DebugLevel)
zerolog.ErrorStackMarshaler = pkgerrors.MarshalStack
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
zerolog.SetGlobalLevel(zerolog.DebugLevel)

vDev := gokbd.NewVirtualKeyboard("gokbd test")
vDev.TypeRune('H')
vDev.TypeRune('e')
Expand Down
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@ module github.com/joshuar/gokbd

go 1.16

require github.com/sirupsen/logrus v1.8.1
require (
github.com/rs/zerolog v1.29.1
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
)
25 changes: 15 additions & 10 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.29.1 h1:cO+d60CHkknCbvzEWxP0S9K6KqyTjrCNUy1LdQLCGPc=
github.com/rs/zerolog v1.29.1/go.mod h1:Le6ESbR7hc+DP6Lt1THiV8CQSdkkNrd3R0XbEgp3ZBU=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
5 changes: 5 additions & 0 deletions keyEvent.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
// Copyright (c) 2023 Joshua Rich <joshua.rich@gmail.com>
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT

package gokbd

// #cgo pkg-config: libevdev
Expand Down
95 changes: 78 additions & 17 deletions keyboard.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
// Copyright (c) 2023 Joshua Rich <joshua.rich@gmail.com>
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT

package gokbd

// #cgo pkg-config: libevdev
Expand All @@ -16,7 +21,7 @@ import (
"time"
"unicode"

log "github.com/sirupsen/logrus"
"github.com/rs/zerolog/log"
)

const devicePath = "/dev/input"
Expand Down Expand Up @@ -47,12 +52,13 @@ func OpenKeyboardDevice(devPath string) *KeyboardDevice {
dev := C.libevdev_new()
fd, err := os.Open(devPath)
if err != nil {
log.Fatalf("Failed to open device: %v", err)
log.Panic().Caller().Err(err).
Msg("Failed to open device.")
}
c_err := C.libevdev_set_fd(dev, C.int(fd.Fd()))
if c_err > 0 {
log.Fatalf("Failed to init libevdev: %v", err)
os.Exit(1)
log.Panic().Caller().Err(err).
Msg("Failed to init libevdev.")
}
return &KeyboardDevice{
dev: dev,
Expand All @@ -66,10 +72,12 @@ func OpenKeyboardDevices() <-chan *KeyboardDevice {
kbdChan := make(chan *KeyboardDevice)
var kbdPaths []string
fileRegexp, _ := regexp.Compile(`event\d+$`)
log.Debug("Looking for keyboards...")
log.Debug().Caller().
Msg("Looking for keyboards...")
err := filepath.WalkDir(devicePath, func(path string, d fs.DirEntry, err error) error {
if err != nil {
log.Errorf("could not read %q: %v\n", path, err)
log.Error().Caller().Err(err).
Msgf("could not read %q.", path)
return err
}
if !d.IsDir() {
Expand All @@ -80,14 +88,17 @@ func OpenKeyboardDevices() <-chan *KeyboardDevice {
return nil
})
if err != nil {
log.Errorf("Couldn't traverse device path: %s, %v", devicePath, err)
log.Error().Caller().Err(err).
Msgf("Couldn't traverse device path: %s.", devicePath)
}
log.Debug("Keyboard search finished.")
log.Debug().Caller().
Msg("Keyboard search finished.")
go func() {
for _, kbdPath := range kbdPaths {
kbd := OpenKeyboardDevice(kbdPath)
if kbd.isKeyboard() {
log.Debugf("Opening keyboard device %s", kbdPath)
log.Debug().Caller().
Msgf("Opening keyboard device %s.", kbdPath)
kbdChan <- kbd
} else {
kbd.Close()
Expand Down Expand Up @@ -128,7 +139,8 @@ func SnoopAllKeyboards(kbds <-chan *KeyboardDevice) <-chan KeyEvent {
}
}
for kbd := range kbds {
log.Debugf("Tracking keys on device %s", kbd.fd.Name())
log.Debug().Caller().
Msgf("Tracking keys on device %s.", kbd.fd.Name())
wg.Add(1)
go kbdSnoop(kbd)
}
Expand All @@ -143,6 +155,8 @@ func SnoopAllKeyboards(kbds <-chan *KeyboardDevice) <-chan KeyEvent {
type VirtualKeyboardDevice struct {
uidev *C.struct_libevdev_uinput
dev *C.struct_libevdev
keys chan *key
wg *sync.WaitGroup
}

// NewVirtualKeyboard will create a new virtual keyboard device (with the name passed in)
Expand All @@ -167,15 +181,35 @@ func NewVirtualKeyboard(name string) *VirtualKeyboardDevice {

rv := C.libevdev_uinput_create_from_device(dev, C.LIBEVDEV_UINPUT_OPEN_MANAGED, &uidev)
if rv > 0 {
log.Errorf("Failed to create new uinput device: %v", rv)
log.Error().Caller().
Msgf("Failed to create new uinput device: %v.", rv)
return nil
}
log.Debugf("Virtual keyboard created at %s", C.GoString(C.libevdev_uinput_get_devnode(uidev)))
log.Debug().Caller().
Msgf("Virtual keyboard created at %s.",
C.GoString(C.libevdev_uinput_get_devnode(uidev)))
time.Sleep(1 * time.Second)
return &VirtualKeyboardDevice{
kbd := &VirtualKeyboardDevice{
uidev: uidev,
dev: dev,
keys: make(chan *key),
wg: &sync.WaitGroup{},
}
go func() {
for {
select {
case k := <-kbd.keys:
kbd.wg.Add(1)
rv := C.libevdev_uinput_write_event(kbd.uidev, C.uint(k.keyType), C.uint(k.keyCode), C.int(k.value))
if rv != 0 {
fmt.Printf("failed send key event type: %v code: %v value %v", k.keyType, k.keyCode, k.value)
}
}
time.Sleep(time.Millisecond)
kbd.wg.Done()
}
}()
return kbd
}

type key struct {
Expand Down Expand Up @@ -223,24 +257,46 @@ func (u *VirtualKeyboardDevice) TypeKey(c int, holdShift bool) {
if holdShift {
errc := u.sendKeys(done, keySequence(keyPress(C.KEY_LEFTSHIFT), keyPress(c), keySync(), keyRelease(c), keySync(), keyRelease(C.KEY_LEFTSHIFT)))
if err := <-errc; err != nil {
log.Errorf("Got error: %v", err)
log.Error().Caller().Err(err).
Msg("Got error.")
}
// keySeq := []*key{keyPress(C.KEY_LEFTSHIFT), keyPress(c), keySync(), keyRelease(c), keySync(), keyRelease(C.KEY_LEFTSHIFT)}
// for _, k := range keySeq {
// u.keys <- k
// }
// u.sendKeys2(keyPress(C.KEY_LEFTSHIFT), keyPress(c), keySync(), keyRelease(c), keySync(), keyRelease(C.KEY_LEFTSHIFT))
} else {
// keySeq := []*key{keyPress(c), keySync(), keyRelease(c), keySync()}
// for _, k := range keySeq {
// u.keys <- k
// }
// u.sendKeys2(keyPress(c), keySync(), keyRelease(c), keySync())
errc := u.sendKeys(done, keySequence(keyPress(c), keySync(), keyRelease(c), keySync()))
if err := <-errc; err != nil {
log.Errorf("Got error: %v", err)
log.Error().Caller().Err(err).
Msg("Got error.")
}
}
}

func (u *VirtualKeyboardDevice) TypeRune(r rune) {
if !unicode.In(r, unicode.PrintRanges...) {
log.Error(fmt.Errorf("rune %c (%U) is not a printable character", r, r))
log.Error().Caller().Err(fmt.Errorf("rune %c (%U) is not a printable character", r, r)).
Msg("Got error.")
}
keyCode, isUpperCase := CodeAndCase(r)
u.TypeKey(keyCode, isUpperCase)
}

func (u *VirtualKeyboardDevice) sendKeys2(keys ...*key) {
for _, k := range keys {
rv := C.libevdev_uinput_write_event(u.uidev, C.uint(k.keyType), C.uint(k.keyCode), C.int(k.value))
if rv < 0 {
fmt.Printf("failed send key event type: %v code: %v value %v", k.keyType, k.keyCode, k.value)
}
}
}

func (u *VirtualKeyboardDevice) sendKeys(done <-chan struct{}, ev ...<-chan *key) <-chan error {
var wg sync.WaitGroup
out := make(chan error)
Expand All @@ -254,6 +310,7 @@ func (u *VirtualKeyboardDevice) sendKeys(done <-chan struct{}, ev ...<-chan *key
if rv < 0 {
out <- fmt.Errorf("failed send key event type: %v code: %v value %v", k.keyType, k.keyCode, k.value)
}
time.Sleep(time.Millisecond)
}
}
wg.Done()
Expand Down Expand Up @@ -292,7 +349,8 @@ func (u *VirtualKeyboardDevice) TypeString(str string) {
break
}
if err != nil {
log.Errorf("Error reading rune in string: %v", err)
log.Error().Caller().Err(err).
Msg("Error reading rune in string.")
}
switch r {
case ' ':
Expand All @@ -305,6 +363,9 @@ func (u *VirtualKeyboardDevice) TypeString(str string) {

// Close will gracefully remove a virtual keyboard, freeing memory and file descriptors
func (u *VirtualKeyboardDevice) Close() {
log.Debug().Caller().
Msg("Closing virtual keyboard device.")
u.wg.Wait()
C.libevdev_uinput_destroy(u.uidev)
C.libevdev_free(u.dev)
}
Expand Down
5 changes: 5 additions & 0 deletions keymodifiers.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
// Copyright (c) 2023 Joshua Rich <joshua.rich@gmail.com>
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT

package gokbd

// KeyModifiers represents the state of any "modifier" keys on the keyboard
Expand Down
5 changes: 5 additions & 0 deletions runemap.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
// Copyright (c) 2023 Joshua Rich <joshua.rich@gmail.com>
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT

package gokbd

// CharVariants represents the upper and lower case variants for a charactor
Expand Down

0 comments on commit 42ecac3

Please sign in to comment.