mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-02-01 23:21:59 +01:00
zsh cleanup and stats (#247)
* better osrelease parsing (ignore garbage at end of string) * add defaultshelltype to telemetry input * track reinit errors by shelltype to see if zsh integration is working
This commit is contained in:
parent
6bcd37c28e
commit
b762df179f
@ -873,10 +873,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("PCLOUD_ENDPOINT=%s\n", pcloud.GetEndpoint())
|
log.Printf("PCLOUD_ENDPOINT=%s\n", pcloud.GetEndpoint())
|
||||||
err = sstore.UpdateCurrentActivity(context.Background(), sstore.ActivityUpdate{NumConns: remote.NumRemotes()}) // set at least one record into activity
|
sstore.UpdateActivityWrap(context.Background(), sstore.ActivityUpdate{NumConns: remote.NumRemotes()}, "numconns") // set at least one record into activity
|
||||||
if err != nil {
|
|
||||||
log.Printf("[error] updating activity: %v\n", err)
|
|
||||||
}
|
|
||||||
installSignalHandlers()
|
installSignalHandlers()
|
||||||
go telemetryLoop()
|
go telemetryLoop()
|
||||||
go stdinReadWatch()
|
go stdinReadWatch()
|
||||||
|
@ -673,11 +673,7 @@ func EvalCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.
|
|||||||
}
|
}
|
||||||
evalDepth := getEvalDepth(ctx)
|
evalDepth := getEvalDepth(ctx)
|
||||||
if pk.Interactive && evalDepth == 0 {
|
if pk.Interactive && evalDepth == 0 {
|
||||||
err := sstore.UpdateCurrentActivity(ctx, sstore.ActivityUpdate{NumCommands: 1})
|
sstore.UpdateActivityWrap(ctx, sstore.ActivityUpdate{NumCommands: 1}, "numcommands")
|
||||||
if err != nil {
|
|
||||||
log.Printf("[error] incrementing activity numcommands: %v\n", err)
|
|
||||||
// fall through (non-fatal error)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if evalDepth > MaxEvalDepth {
|
if evalDepth > MaxEvalDepth {
|
||||||
return nil, fmt.Errorf("alias/history expansion max-depth exceeded")
|
return nil, fmt.Errorf("alias/history expansion max-depth exceeded")
|
||||||
@ -2753,10 +2749,7 @@ func validateRemoteColor(color string, typeStr string) error {
|
|||||||
|
|
||||||
func SessionOpenSharedCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) {
|
func SessionOpenSharedCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) {
|
||||||
activity := sstore.ActivityUpdate{ClickShared: 1}
|
activity := sstore.ActivityUpdate{ClickShared: 1}
|
||||||
err := sstore.UpdateCurrentActivity(ctx, activity)
|
sstore.UpdateActivityWrap(ctx, activity, "click-shared")
|
||||||
if err != nil {
|
|
||||||
log.Printf("error updating click-shared: %v\n", err)
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("shared sessions are not available in this version of prompt (stay tuned)")
|
return nil, fmt.Errorf("shared sessions are not available in this version of prompt (stay tuned)")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3213,10 +3206,7 @@ func HistoryCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (ssto
|
|||||||
}
|
}
|
||||||
show := !resolveBool(pk.Kwargs["noshow"], false)
|
show := !resolveBool(pk.Kwargs["noshow"], false)
|
||||||
if show {
|
if show {
|
||||||
err = sstore.UpdateCurrentActivity(ctx, sstore.ActivityUpdate{HistoryView: 1})
|
sstore.UpdateActivityWrap(ctx, sstore.ActivityUpdate{HistoryView: 1}, "history")
|
||||||
if err != nil {
|
|
||||||
log.Printf("error updating current activity (history): %v\n", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
update := &sstore.ModelUpdate{}
|
update := &sstore.ModelUpdate{}
|
||||||
update.History = &sstore.HistoryInfoType{
|
update.History = &sstore.HistoryInfoType{
|
||||||
@ -3453,10 +3443,7 @@ func BookmarksShowCommand(ctx context.Context, pk *scpacket.FeCommandPacketType)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot retrieve bookmarks: %v", err)
|
return nil, fmt.Errorf("cannot retrieve bookmarks: %v", err)
|
||||||
}
|
}
|
||||||
err = sstore.UpdateCurrentActivity(ctx, sstore.ActivityUpdate{BookmarksView: 1})
|
sstore.UpdateActivityWrap(ctx, sstore.ActivityUpdate{BookmarksView: 1}, "bookmarks")
|
||||||
if err != nil {
|
|
||||||
log.Printf("error updating current activity (bookmarks): %v\n", err)
|
|
||||||
}
|
|
||||||
update := &sstore.ModelUpdate{
|
update := &sstore.ModelUpdate{
|
||||||
MainView: sstore.MainViewBookmarks,
|
MainView: sstore.MainViewBookmarks,
|
||||||
Bookmarks: bms,
|
Bookmarks: bms,
|
||||||
@ -4504,7 +4491,7 @@ func ClientShowCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (s
|
|||||||
buf.WriteString(fmt.Sprintf(" %-15s %d\n", "db-version", dbVersion))
|
buf.WriteString(fmt.Sprintf(" %-15s %d\n", "db-version", dbVersion))
|
||||||
buf.WriteString(fmt.Sprintf(" %-15s %s\n", "client-version", clientVersion))
|
buf.WriteString(fmt.Sprintf(" %-15s %s\n", "client-version", clientVersion))
|
||||||
buf.WriteString(fmt.Sprintf(" %-15s %s %s\n", "server-version", scbase.WaveVersion, scbase.BuildTime))
|
buf.WriteString(fmt.Sprintf(" %-15s %s %s\n", "server-version", scbase.WaveVersion, scbase.BuildTime))
|
||||||
buf.WriteString(fmt.Sprintf(" %-15s %s (%s)\n", "arch", scbase.ClientArch(), scbase.MacOSRelease()))
|
buf.WriteString(fmt.Sprintf(" %-15s %s (%s)\n", "arch", scbase.ClientArch(), scbase.UnameKernelRelease()))
|
||||||
update := &sstore.ModelUpdate{
|
update := &sstore.ModelUpdate{
|
||||||
Info: &sstore.InfoMsgType{
|
Info: &sstore.InfoMsgType{
|
||||||
InfoTitle: fmt.Sprintf("client info"),
|
InfoTitle: fmt.Sprintf("client info"),
|
||||||
|
@ -18,6 +18,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/wavetermdev/waveterm/waveshell/pkg/shellapi"
|
||||||
"github.com/wavetermdev/waveterm/wavesrv/pkg/dbutil"
|
"github.com/wavetermdev/waveterm/wavesrv/pkg/dbutil"
|
||||||
"github.com/wavetermdev/waveterm/wavesrv/pkg/rtnstate"
|
"github.com/wavetermdev/waveterm/wavesrv/pkg/rtnstate"
|
||||||
"github.com/wavetermdev/waveterm/wavesrv/pkg/scbase"
|
"github.com/wavetermdev/waveterm/wavesrv/pkg/scbase"
|
||||||
@ -164,7 +165,8 @@ func SendTelemetry(ctx context.Context, force bool) error {
|
|||||||
}
|
}
|
||||||
log.Printf("[pcloud] sending telemetry data\n")
|
log.Printf("[pcloud] sending telemetry data\n")
|
||||||
dayStr := sstore.GetCurDayStr()
|
dayStr := sstore.GetCurDayStr()
|
||||||
input := TelemetryInputType{UserId: clientData.UserId, ClientId: clientData.ClientId, CurDay: dayStr, Activity: activity}
|
defaultShellType := shellapi.DetectLocalShellType()
|
||||||
|
input := TelemetryInputType{UserId: clientData.UserId, ClientId: clientData.ClientId, CurDay: dayStr, DefaultShell: defaultShellType, Activity: activity}
|
||||||
req, err := makeAnonPostReq(ctx, TelemetryUrl, input)
|
req, err := makeAnonPostReq(ctx, TelemetryUrl, input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -22,6 +22,7 @@ type TelemetryInputType struct {
|
|||||||
UserId string `json:"userid"`
|
UserId string `json:"userid"`
|
||||||
ClientId string `json:"clientid"`
|
ClientId string `json:"clientid"`
|
||||||
CurDay string `json:"curday"`
|
CurDay string `json:"curday"`
|
||||||
|
DefaultShell string `json:"defaultshell"`
|
||||||
Activity []*sstore.ActivityType `json:"activity"`
|
Activity []*sstore.ActivityType `json:"activity"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1103,6 +1103,16 @@ func getStateVarsFromInitPk(initPk *packet.InitPacketType) map[string]string {
|
|||||||
return rtn
|
return rtn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func makeReinitErrorUpdate(shellType string) sstore.ActivityUpdate {
|
||||||
|
rtn := sstore.ActivityUpdate{}
|
||||||
|
if shellType == packet.ShellType_bash {
|
||||||
|
rtn.ReinitBashErrors = 1
|
||||||
|
} else if shellType == packet.ShellType_zsh {
|
||||||
|
rtn.ReinitZshErrors = 1
|
||||||
|
}
|
||||||
|
return rtn
|
||||||
|
}
|
||||||
|
|
||||||
func (msh *MShellProc) ReInit(ctx context.Context, shellType string) (*packet.ShellStatePacketType, error) {
|
func (msh *MShellProc) ReInit(ctx context.Context, shellType string) (*packet.ShellStatePacketType, error) {
|
||||||
if !msh.IsConnected() {
|
if !msh.IsConnected() {
|
||||||
return nil, fmt.Errorf("cannot reinit, remote is not connected")
|
return nil, fmt.Errorf("cannot reinit, remote is not connected")
|
||||||
@ -1122,12 +1132,14 @@ func (msh *MShellProc) ReInit(ctx context.Context, shellType string) (*packet.Sh
|
|||||||
}
|
}
|
||||||
ssPk, ok := resp.(*packet.ShellStatePacketType)
|
ssPk, ok := resp.(*packet.ShellStatePacketType)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
sstore.UpdateActivityWrap(ctx, makeReinitErrorUpdate(shellType), "reiniterror")
|
||||||
if respPk, ok := resp.(*packet.ResponsePacketType); ok && respPk.Error != "" {
|
if respPk, ok := resp.(*packet.ResponsePacketType); ok && respPk.Error != "" {
|
||||||
return nil, fmt.Errorf("error reinitializing remote: %s", respPk.Error)
|
return nil, fmt.Errorf("error reinitializing remote: %s", respPk.Error)
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("invalid reinit response (not an shellstate packet): %T", resp)
|
return nil, fmt.Errorf("invalid reinit response (not an shellstate packet): %T", resp)
|
||||||
}
|
}
|
||||||
if ssPk.State == nil {
|
if ssPk.State == nil {
|
||||||
|
sstore.UpdateActivityWrap(ctx, makeReinitErrorUpdate(shellType), "reiniterror")
|
||||||
return nil, fmt.Errorf("invalid reinit response shellstate packet does not contain remote state")
|
return nil, fmt.Errorf("invalid reinit response shellstate packet does not contain remote state")
|
||||||
}
|
}
|
||||||
// TODO: maybe we don't need to save statebase here. should be possible to save it on demand
|
// TODO: maybe we don't need to save statebase here. should be possible to save it on demand
|
||||||
|
@ -351,11 +351,11 @@ func ClientArch() string {
|
|||||||
return fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)
|
return fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)
|
||||||
}
|
}
|
||||||
|
|
||||||
var releaseRegex = regexp.MustCompile(`^\d+\.\d+\.\d+$`)
|
var releaseRegex = regexp.MustCompile(`^(\d+\.\d+\.\d+)`)
|
||||||
var osReleaseOnce = &sync.Once{}
|
var osReleaseOnce = &sync.Once{}
|
||||||
var osRelease string
|
var osRelease string
|
||||||
|
|
||||||
func macOSRelease() string {
|
func unameKernelRelease() string {
|
||||||
ctx, cancelFn := context.WithTimeout(context.Background(), 2*time.Second)
|
ctx, cancelFn := context.WithTimeout(context.Background(), 2*time.Second)
|
||||||
defer cancelFn()
|
defer cancelFn()
|
||||||
out, err := exec.CommandContext(ctx, "uname", "-r").CombinedOutput()
|
out, err := exec.CommandContext(ctx, "uname", "-r").CombinedOutput()
|
||||||
@ -364,16 +364,17 @@ func macOSRelease() string {
|
|||||||
return "-"
|
return "-"
|
||||||
}
|
}
|
||||||
releaseStr := strings.TrimSpace(string(out))
|
releaseStr := strings.TrimSpace(string(out))
|
||||||
if !releaseRegex.MatchString(releaseStr) {
|
m := releaseRegex.FindStringSubmatch(releaseStr)
|
||||||
|
if m == nil || len(m) < 2 {
|
||||||
log.Printf("invalid uname -r output: [%s]\n", releaseStr)
|
log.Printf("invalid uname -r output: [%s]\n", releaseStr)
|
||||||
return "-"
|
return "-"
|
||||||
}
|
}
|
||||||
return releaseStr
|
return m[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
func MacOSRelease() string {
|
func UnameKernelRelease() string {
|
||||||
osReleaseOnce.Do(func() {
|
osReleaseOnce.Do(func() {
|
||||||
osRelease = macOSRelease()
|
osRelease = unameKernelRelease()
|
||||||
})
|
})
|
||||||
return osRelease
|
return osRelease
|
||||||
}
|
}
|
||||||
|
@ -2157,6 +2157,15 @@ func GetCurDayStr() string {
|
|||||||
return dayStr
|
return dayStr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wraps UpdateCurrentActivity, but ignores errors
|
||||||
|
func UpdateActivityWrap(ctx context.Context, update ActivityUpdate, debugStr string) {
|
||||||
|
err := UpdateCurrentActivity(ctx, update)
|
||||||
|
if err != nil {
|
||||||
|
// ignore error, just log, since this is not critical
|
||||||
|
log.Printf("error updating current activity (%s): %v\n", debugStr, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func UpdateCurrentActivity(ctx context.Context, update ActivityUpdate) error {
|
func UpdateCurrentActivity(ctx context.Context, update ActivityUpdate) error {
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
dayStr := GetCurDayStr()
|
dayStr := GetCurDayStr()
|
||||||
@ -2171,7 +2180,7 @@ func UpdateCurrentActivity(ctx context.Context, update ActivityUpdate) error {
|
|||||||
if len(tzName) > MaxTzNameLen {
|
if len(tzName) > MaxTzNameLen {
|
||||||
tzName = tzName[0:MaxTzNameLen]
|
tzName = tzName[0:MaxTzNameLen]
|
||||||
}
|
}
|
||||||
tx.Exec(query, dayStr, tdata, tzName, tzOffset, scbase.WaveVersion, scbase.ClientArch(), scbase.BuildTime, scbase.MacOSRelease())
|
tx.Exec(query, dayStr, tdata, tzName, tzOffset, scbase.WaveVersion, scbase.ClientArch(), scbase.BuildTime, scbase.UnameKernelRelease())
|
||||||
}
|
}
|
||||||
tdata.NumCommands += update.NumCommands
|
tdata.NumCommands += update.NumCommands
|
||||||
tdata.FgMinutes += update.FgMinutes
|
tdata.FgMinutes += update.FgMinutes
|
||||||
@ -2180,6 +2189,8 @@ func UpdateCurrentActivity(ctx context.Context, update ActivityUpdate) error {
|
|||||||
tdata.ClickShared += update.ClickShared
|
tdata.ClickShared += update.ClickShared
|
||||||
tdata.HistoryView += update.HistoryView
|
tdata.HistoryView += update.HistoryView
|
||||||
tdata.BookmarksView += update.BookmarksView
|
tdata.BookmarksView += update.BookmarksView
|
||||||
|
tdata.ReinitBashErrors += update.ReinitBashErrors
|
||||||
|
tdata.ReinitZshErrors += update.ReinitZshErrors
|
||||||
if update.NumConns > 0 {
|
if update.NumConns > 0 {
|
||||||
tdata.NumConns = update.NumConns
|
tdata.NumConns = update.NumConns
|
||||||
}
|
}
|
||||||
|
@ -235,6 +235,8 @@ type ActivityUpdate struct {
|
|||||||
BookmarksView int
|
BookmarksView int
|
||||||
NumConns int
|
NumConns int
|
||||||
WebShareLimit int
|
WebShareLimit int
|
||||||
|
ReinitBashErrors int
|
||||||
|
ReinitZshErrors int
|
||||||
BuildTime string
|
BuildTime string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,6 +249,7 @@ type ActivityType struct {
|
|||||||
ClientVersion string `json:"clientversion"`
|
ClientVersion string `json:"clientversion"`
|
||||||
ClientArch string `json:"clientarch"`
|
ClientArch string `json:"clientarch"`
|
||||||
BuildTime string `json:"buildtime"`
|
BuildTime string `json:"buildtime"`
|
||||||
|
DefaultShell string `json:"defaultshell"`
|
||||||
OSRelease string `json:"osrelease"`
|
OSRelease string `json:"osrelease"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,6 +263,8 @@ type TelemetryData struct {
|
|||||||
BookmarksView int `json:"bookmarksview,omitempty"`
|
BookmarksView int `json:"bookmarksview,omitempty"`
|
||||||
NumConns int `json:"numconns"`
|
NumConns int `json:"numconns"`
|
||||||
WebShareLimit int `json:"websharelimit,omitempty"`
|
WebShareLimit int `json:"websharelimit,omitempty"`
|
||||||
|
ReinitBashErrors int `json:"reinitbasherrors,omitempty"`
|
||||||
|
ReinitZshErrors int `json:"reinitzsherrors,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tdata TelemetryData) Value() (driver.Value, error) {
|
func (tdata TelemetryData) Value() (driver.Value, error) {
|
||||||
|
Loading…
Reference in New Issue
Block a user