github.com/distbuild/reclient@v0.0.0-20240401075343-3de72e395564/cmd/dumpstats/main.go (about) 1 // Copyright 2023 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package main is the main package for the dumpstats binary which produces RE client stats. 16 // 17 // This tool currently provides a workaround for dumping stats in an Android build dist_dir, which 18 // is later added to a database queryable by dremel. It relies on a parsing of reproxy record logs. 19 package main 20 21 import ( 22 "flag" 23 "os" 24 25 lpb "github.com/bazelbuild/reclient/api/log" 26 "github.com/bazelbuild/reclient/internal/pkg/bootstrap" 27 "github.com/bazelbuild/reclient/internal/pkg/logger" 28 "github.com/bazelbuild/reclient/internal/pkg/rbeflag" 29 "github.com/bazelbuild/reclient/internal/pkg/stats" 30 "github.com/bazelbuild/reclient/pkg/version" 31 32 "github.com/bazelbuild/remote-apis-sdks/go/pkg/moreflag" 33 log "github.com/golang/glog" 34 ) 35 36 var ( 37 proxyLogDir []string 38 shutdownProxy = flag.Bool("shutdown_proxy", false, "Whether to shut down the proxy before reading the log file.") 39 shutdownSeconds = flag.Int("shutdown_seconds", 5, "Number of seconds to wait for reproxy to shut down") 40 serverAddr = flag.String("server_address", "127.0.0.1:8000", "The server address in the format of host:port for network, or unix:///file for unix domain sockets.") 41 logFormat = flag.String("log_format", "text", "Format of proxy log. Currently only text is supported.") 42 logPath = flag.String("log_path", "", "DEPRECATED. Use proxy_log_dir instead. If provided, the path to a log file of all executed records. The format is e.g. text://full/file/path.") 43 outputDir = flag.String("output_dir", os.TempDir(), "The location to which stats should be written.") 44 ) 45 46 // TODO(b/277909914): remove this binary, it is now superseded by bootstrap --shutdown. 47 func main() { 48 defer log.Flush() 49 flag.Var((*moreflag.StringListValue)(&proxyLogDir), "proxy_log_dir", "Comma-separated list of directory paths to aggregate proxy logs from.") 50 rbeflag.Parse() 51 version.PrintAndExitOnVersionFlag(true) 52 53 if *logPath == "" && len(proxyLogDir) == 0 { 54 log.Fatal("Must provide proxy log path.") 55 } 56 if *outputDir == "" { 57 log.Fatal("Must provide an output directory.") 58 } 59 60 if *shutdownProxy { 61 bootstrap.ShutDownProxy(*serverAddr, *shutdownSeconds) 62 } 63 64 var recs []*lpb.LogRecord 65 var pInfos []*lpb.ProxyInfo 66 if len(proxyLogDir) > 0 { 67 log.Infof("Aggregating stats from %v...", proxyLogDir) 68 format, err := logger.ParseFormat(*logFormat) 69 if err != nil { 70 log.Errorf("Failed parsing logFormat, %v, to format: %v", *logFormat, err) 71 } else { 72 recs, pInfos, err = logger.ParseFromLogDirs(format, proxyLogDir) 73 if err != nil { 74 log.Errorf("Failed reading proxy log: %v", err) 75 } 76 } 77 } else { 78 log.Infof("Aggregating stats from %v...", *logPath) 79 var err error 80 recs, err = logger.ParseFromFormatFile(*logPath) 81 if err != nil { 82 log.Errorf("Failed reading proxy log: %v", err) 83 } 84 } 85 // If failed parsing logFormat string, or failed reading the log file, 86 // we still keep recs and pInfos as nil, and produce output files that 87 // includes the environment variables and other things. 88 stats.WriteFromRecords(recs, pInfos, *outputDir) 89 }