Merge commit '6bd7fac875d9e9009915053d8a590abb372c5679' into feature/livekit-upgrade-1.13.1
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
@@ -23,10 +24,12 @@ import (
|
||||
|
||||
"github.com/dustin/go-humanize"
|
||||
"github.com/olekukonko/tablewriter"
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/olekukonko/tablewriter/tw"
|
||||
"github.com/urfave/cli/v3"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/livekit/protocol/auth"
|
||||
"github.com/livekit/protocol/livekit"
|
||||
"github.com/livekit/protocol/utils"
|
||||
"github.com/livekit/protocol/utils/guid"
|
||||
|
||||
@@ -35,7 +38,7 @@ import (
|
||||
"github.com/livekit/livekit-server/pkg/service"
|
||||
)
|
||||
|
||||
func generateKeys(_ *cli.Context) error {
|
||||
func generateKeys(_ context.Context, _ *cli.Command) error {
|
||||
apiKey := guid.New(utils.APIKeyPrefix)
|
||||
secret := utils.RandomSecret()
|
||||
fmt.Println("API Key: ", apiKey)
|
||||
@@ -43,7 +46,7 @@ func generateKeys(_ *cli.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func printPorts(c *cli.Context) error {
|
||||
func printPorts(_ context.Context, c *cli.Command) error {
|
||||
conf, err := getConfig(c)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -84,17 +87,21 @@ func printPorts(c *cli.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func helpVerbose(c *cli.Context) error {
|
||||
func helpVerbose(_ context.Context, c *cli.Command) error {
|
||||
generatedFlags, err := config.GenerateCLIFlags(baseFlags, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.App.Flags = append(baseFlags, generatedFlags...)
|
||||
flags := append([]cli.Flag{}, baseFlags...)
|
||||
flags = append(flags, generatedFlags...)
|
||||
root := c.Root()
|
||||
root.Flags = flags
|
||||
c.Flags = flags
|
||||
return cli.ShowAppHelp(c)
|
||||
}
|
||||
|
||||
func createToken(c *cli.Context) error {
|
||||
func createToken(_ context.Context, c *cli.Command) error {
|
||||
room := c.String("room")
|
||||
identity := c.String("identity")
|
||||
|
||||
@@ -160,7 +167,7 @@ func createToken(c *cli.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func listNodes(c *cli.Context) error {
|
||||
func listNodes(_ context.Context, c *cli.Command) error {
|
||||
conf, err := getConfig(c)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -181,10 +188,27 @@ func listNodes(c *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
table := tablewriter.NewWriter(os.Stdout)
|
||||
table.SetRowLine(true)
|
||||
table.SetAutoWrapText(false)
|
||||
table.SetHeader([]string{
|
||||
table := tablewriter.NewTable(os.Stdout,
|
||||
tablewriter.WithHeaderAutoFormat(tw.Off),
|
||||
tablewriter.WithRowAutoWrap(0),
|
||||
tablewriter.WithRendition(tw.Rendition{
|
||||
Settings: tw.Settings{
|
||||
Separators: tw.Separators{BetweenRows: tw.On},
|
||||
},
|
||||
}),
|
||||
tablewriter.WithRowAlignmentConfig(tw.CellAlignment{
|
||||
PerColumn: []tw.Align{
|
||||
tw.AlignCenter, tw.AlignCenter, tw.AlignCenter,
|
||||
tw.AlignRight, tw.AlignRight,
|
||||
tw.AlignRight,
|
||||
tw.AlignRight, tw.AlignRight,
|
||||
tw.AlignRight, tw.AlignRight, tw.AlignRight,
|
||||
tw.AlignRight, tw.AlignRight,
|
||||
tw.AlignCenter,
|
||||
},
|
||||
}),
|
||||
)
|
||||
table.Header(
|
||||
"ID", "IP Address", "Region",
|
||||
"CPUs", "CPU Usage\nLoad Avg",
|
||||
"Memory Used/Total",
|
||||
@@ -192,19 +216,14 @@ func listNodes(c *cli.Context) error {
|
||||
"Bytes/s In/Out\nBytes Total", "Packets/s In/Out\nPackets Total", "System Dropped Pkts/s\nPkts/s Out/Dropped",
|
||||
"Nack/s\nNack Total", "Retrans/s\nRetrans Total",
|
||||
"Started At\nUpdated At",
|
||||
})
|
||||
table.SetColumnAlignment([]int{
|
||||
tablewriter.ALIGN_CENTER, tablewriter.ALIGN_CENTER, tablewriter.ALIGN_CENTER,
|
||||
tablewriter.ALIGN_RIGHT, tablewriter.ALIGN_RIGHT,
|
||||
tablewriter.ALIGN_RIGHT,
|
||||
tablewriter.ALIGN_RIGHT, tablewriter.ALIGN_RIGHT,
|
||||
tablewriter.ALIGN_RIGHT, tablewriter.ALIGN_RIGHT, tablewriter.ALIGN_RIGHT,
|
||||
tablewriter.ALIGN_RIGHT, tablewriter.ALIGN_RIGHT,
|
||||
tablewriter.ALIGN_CENTER,
|
||||
})
|
||||
)
|
||||
|
||||
for _, node := range nodes {
|
||||
stats := node.Stats
|
||||
rate := &livekit.NodeStatsRate{}
|
||||
if len(stats.Rates) > 0 {
|
||||
rate = stats.Rates[0]
|
||||
}
|
||||
|
||||
// Id and state
|
||||
idAndState := fmt.Sprintf("%s\n(%s)", node.Id, node.State.Enum().String())
|
||||
@@ -220,19 +239,23 @@ func listNodes(c *cli.Context) error {
|
||||
clientsAndTracks := fmt.Sprintf("%d\n%d / %d", stats.NumClients, stats.NumTracksIn, stats.NumTracksOut)
|
||||
|
||||
// Packet stats
|
||||
bytes := fmt.Sprintf("%sps / %sps\n%s / %s", humanize.Bytes(uint64(stats.BytesInPerSec)), humanize.Bytes(uint64(stats.BytesOutPerSec)),
|
||||
bytes := fmt.Sprintf("%sps / %sps\n%s / %s", humanize.Bytes(uint64(rate.BytesIn)), humanize.Bytes(uint64(rate.BytesOut)),
|
||||
humanize.Bytes(stats.BytesIn), humanize.Bytes(stats.BytesOut))
|
||||
packets := fmt.Sprintf("%s / %s\n%s / %s", humanize.Comma(int64(stats.PacketsInPerSec)), humanize.Comma(int64(stats.PacketsOutPerSec)),
|
||||
packets := fmt.Sprintf("%s / %s\n%s / %s", humanize.Comma(int64(rate.PacketsIn)), humanize.Comma(int64(rate.PacketsOut)),
|
||||
strings.TrimSpace(humanize.SIWithDigits(float64(stats.PacketsIn), 2, "")), strings.TrimSpace(humanize.SIWithDigits(float64(stats.PacketsOut), 2, "")))
|
||||
sysPackets := fmt.Sprintf("%.2f %%\n%v / %v", stats.SysPacketsDroppedPctPerSec*100, float64(stats.SysPacketsOutPerSec), float64(stats.SysPacketsDroppedPerSec))
|
||||
nacks := fmt.Sprintf("%.2f\n%s", stats.NackPerSec, strings.TrimSpace(humanize.SIWithDigits(float64(stats.NackTotal), 2, "")))
|
||||
retransmit := fmt.Sprintf("%.2f\n%s", stats.RetransmitPacketsOutPerSec, strings.TrimSpace(humanize.SIWithDigits(float64(stats.RetransmitPacketsOut), 2, "")))
|
||||
sysPacketsDroppedPct := float32(0)
|
||||
if rate.SysPacketsOut+rate.SysPacketsDropped > 0 {
|
||||
sysPacketsDroppedPct = float32(rate.SysPacketsDropped) / float32(rate.SysPacketsDropped+rate.SysPacketsOut)
|
||||
}
|
||||
sysPackets := fmt.Sprintf("%.2f %%\n%v / %v", sysPacketsDroppedPct*100, float64(rate.SysPacketsOut), float64(rate.SysPacketsDropped))
|
||||
nacks := fmt.Sprintf("%.2f\n%s", rate.NackTotal, strings.TrimSpace(humanize.SIWithDigits(float64(stats.NackTotal), 2, "")))
|
||||
retransmit := fmt.Sprintf("%.2f\n%s", rate.RetransmitPacketsOut, strings.TrimSpace(humanize.SIWithDigits(float64(stats.RetransmitPacketsOut), 2, "")))
|
||||
|
||||
// Date
|
||||
startedAndUpdated := fmt.Sprintf("%s\n%s", time.Unix(stats.StartedAt, 0).UTC().UTC().Format("2006-01-02 15:04:05"),
|
||||
time.Unix(stats.UpdatedAt, 0).UTC().Format("2006-01-02 15:04:05"))
|
||||
|
||||
table.Append([]string{
|
||||
table.Append(
|
||||
idAndState, node.Ip, node.Region,
|
||||
cpus, cpuUsageAndLoadAvg,
|
||||
memUsage,
|
||||
@@ -240,9 +263,9 @@ func listNodes(c *cli.Context) error {
|
||||
bytes, packets, sysPackets,
|
||||
nacks, retransmit,
|
||||
startedAndUpdated,
|
||||
})
|
||||
)
|
||||
}
|
||||
table.Render()
|
||||
table.Render() //nolint:errcheck
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net"
|
||||
@@ -25,15 +26,16 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"github.com/urfave/cli/v3"
|
||||
|
||||
"github.com/livekit/livekit-server/pkg/rtc"
|
||||
"github.com/livekit/livekit-server/pkg/telemetry/prometheus"
|
||||
"github.com/livekit/protocol/logger"
|
||||
"github.com/livekit/protocol/tracer/jaeger"
|
||||
|
||||
"github.com/livekit/livekit-server/pkg/config"
|
||||
"github.com/livekit/livekit-server/pkg/routing"
|
||||
"github.com/livekit/livekit-server/pkg/rtc"
|
||||
"github.com/livekit/livekit-server/pkg/service"
|
||||
"github.com/livekit/livekit-server/pkg/telemetry/prometheus"
|
||||
"github.com/livekit/livekit-server/version"
|
||||
)
|
||||
|
||||
@@ -49,7 +51,7 @@ var baseFlags = []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "config-body",
|
||||
Usage: "LiveKit config in YAML, typically passed in as an environment var in a container",
|
||||
EnvVars: []string{"LIVEKIT_CONFIG"},
|
||||
Sources: cli.EnvVars("LIVEKIT_CONFIG"),
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "key-file",
|
||||
@@ -58,44 +60,47 @@ var baseFlags = []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "keys",
|
||||
Usage: "api keys (key: secret\\n)",
|
||||
EnvVars: []string{"LIVEKIT_KEYS"},
|
||||
Sources: cli.EnvVars("LIVEKIT_KEYS"),
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "region",
|
||||
Usage: "region of the current node. Used by regionaware node selector",
|
||||
EnvVars: []string{"LIVEKIT_REGION"},
|
||||
Sources: cli.EnvVars("LIVEKIT_REGION"),
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "node-ip",
|
||||
Usage: "IP address of the current node, used to advertise to clients. Automatically determined by default",
|
||||
EnvVars: []string{"NODE_IP"},
|
||||
Sources: cli.EnvVars("NODE_IP"),
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "udp-port",
|
||||
Usage: "UDP port(s) to use for WebRTC traffic",
|
||||
EnvVars: []string{"UDP_PORT"},
|
||||
Sources: cli.EnvVars("UDP_PORT"),
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "redis-host",
|
||||
Usage: "host (incl. port) to redis server",
|
||||
EnvVars: []string{"REDIS_HOST"},
|
||||
Sources: cli.EnvVars("REDIS_HOST"),
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "redis-password",
|
||||
Usage: "password to redis",
|
||||
EnvVars: []string{"REDIS_PASSWORD"},
|
||||
Sources: cli.EnvVars("REDIS_PASSWORD"),
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "turn-cert",
|
||||
Usage: "tls cert file for TURN server",
|
||||
EnvVars: []string{"LIVEKIT_TURN_CERT"},
|
||||
Sources: cli.EnvVars("LIVEKIT_TURN_CERT"),
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "turn-key",
|
||||
Usage: "tls key file for TURN server",
|
||||
EnvVars: []string{"LIVEKIT_TURN_KEY"},
|
||||
Sources: cli.EnvVars("LIVEKIT_TURN_KEY"),
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "cpuprofile",
|
||||
Usage: "write CPU profile to `file`",
|
||||
},
|
||||
// debugging flags
|
||||
&cli.StringFlag{
|
||||
Name: "memprofile",
|
||||
Usage: "write memory profile to `file`",
|
||||
@@ -127,7 +132,7 @@ func main() {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
app := &cli.App{
|
||||
cmd := &cli.Command{
|
||||
Name: "livekit-server",
|
||||
Usage: "High performance WebRTC server",
|
||||
Description: "run without subcommands to start the server",
|
||||
@@ -182,21 +187,18 @@ func main() {
|
||||
Version: version.Version,
|
||||
}
|
||||
|
||||
if err := app.Run(os.Args); err != nil {
|
||||
if err := cmd.Run(context.Background(), os.Args); err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
func getConfig(c *cli.Context) (*config.Config, error) {
|
||||
func getConfig(c *cli.Command) (*config.Config, error) {
|
||||
confString, err := getConfigString(c.String("config"), c.String("config-body"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
strictMode := true
|
||||
if c.Bool("disable-strict-config") {
|
||||
strictMode = false
|
||||
}
|
||||
strictMode := !c.Bool("disable-strict-config")
|
||||
|
||||
conf, err := config.NewConfig(confString, strictMode, c, baseFlags)
|
||||
if err != nil {
|
||||
@@ -242,11 +244,14 @@ func getConfig(c *cli.Context) (*config.Config, error) {
|
||||
return conf, nil
|
||||
}
|
||||
|
||||
func startServer(c *cli.Context) error {
|
||||
func startServer(ctx context.Context, c *cli.Command) error {
|
||||
conf, err := getConfig(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if url := conf.Trace.JaegerURL; url != "" {
|
||||
jaeger.Configure(ctx, url, "livekit")
|
||||
}
|
||||
|
||||
// validate API key length
|
||||
err = conf.ValidateKeys()
|
||||
@@ -254,6 +259,25 @@ func startServer(c *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = conf.LoadTURNSecrets(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if cpuProfile := c.String("cpuprofile"); cpuProfile != "" {
|
||||
if f, err := os.Create(cpuProfile); err != nil {
|
||||
return err
|
||||
} else {
|
||||
if err := pprof.StartCPUProfile(f); err != nil {
|
||||
f.Close()
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
pprof.StopCPUProfile()
|
||||
f.Close()
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
if memProfile := c.String("memprofile"); memProfile != "" {
|
||||
if f, err := os.Create(memProfile); err != nil {
|
||||
return err
|
||||
@@ -285,7 +309,7 @@ func startServer(c *cli.Context) error {
|
||||
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
|
||||
|
||||
go func() {
|
||||
for i := 0; i < 2; i++ {
|
||||
for i := range 2 {
|
||||
sig := <-sigChan
|
||||
force := i > 0
|
||||
logger.Infow("exit requested, shutting down", "signal", sig, "force", force)
|
||||
|
||||
Reference in New Issue
Block a user