This is a simple implementation of a cross-platform key logger in Go.
-
Windows
Implemented through the
SetWindowsHookExW(WH_KEYBOARD_LL)API. -
Linux
Implemented through the
/dev/input/event/filesystem API.(See dev-input for more information.)
Important
On Linux, root is required to read keyboard events.
go get github.com/nathan-fiscaletti/key-loggerRaw keyboard events will include both the key pressed and the key released events.
View Documentation: ./cmd/example/raw/main.go
Tip
Run this example with: go run ./cmd/example/raw or use the built in VSCode Run Configuration.
package main
import (
"fmt"
"github.com/nathan-fiscaletti/key-logger/pkg/key"
"github.com/nathan-fiscaletti/key-logger/pkg/keyboard"
"context"
)
func main() {
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
kb := keyboard.New()
err := kb.Listen(ctx, func(event keyboard.Event) {
fmt.Printf("Key: %s, Event: %s\n", event.Key.Name, event.EventType)
if event.Key.Equals(key.Escape) {
cancel()
}
})
if err != nil {
fmt.Printf("Error listening for keyboard events: %v\n", err)
return
}
fmt.Println("Listening for keyboard events...")
<-ctx.Done()
}The key listener will only include the key released events, but each event will also include a list of modifier keys that were pressed at the time of the event.
View Documentation: ./cmd/example/keylistener/main.go
You can use key.IsModifierKey to check if a key is a modifier key.
Tip
Run this example with: go run ./cmd/example/keylistener or use the built in VSCode Run Configuration.
package main
import (
"fmt"
"log"
"github.com/nathan-fiscaletti/key-logger/pkg/key"
"github.com/nathan-fiscaletti/key-logger/pkg/keyboard"
"github.com/nathan-fiscaletti/key-logger/pkg/listener"
"github.com/samber/lo"
"context"
)
func main() {
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
kb := keyboard.New()
kl := listener.New(kb)
err := kl.Listen(ctx, func(event listener.KeyEvent) {
fmt.Printf(
"Key: %v, Modifiers: %v\n",
event.Key.Name,
lo.Map(
lo.Filter(event.Modifiers, func(k key.Key, _ int) bool {
return key.IsModifierKey(k)
}),
func(k key.Key, _ int) string { return k.Name },
),
)
if event.Key.Equals(key.Escape) {
cancel()
}
})
if err != nil {
log.Fatal("Error listening for keyboard events: %v\n", err)
return
}
fmt.Println("Listening for keyboard events...")
<-ctx.Done()
}