You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

110 lines
3.1 KiB

  1. // Copyright 2014 Google Inc. All Rights Reserved.
  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. // pprof is a tool for collection, manipulation and visualization
  15. // of performance profiles.
  16. package main
  17. import (
  18. "fmt"
  19. "os"
  20. "strings"
  21. "syscall"
  22. "github.com/chzyer/readline"
  23. "github.com/google/pprof/driver"
  24. )
  25. func main() {
  26. if err := driver.PProf(&driver.Options{UI: newUI()}); err != nil {
  27. fmt.Fprintf(os.Stderr, "pprof: %v\n", err)
  28. os.Exit(2)
  29. }
  30. }
  31. // readlineUI implements the driver.UI interface using the
  32. // github.com/chzyer/readline library.
  33. // This is contained in pprof.go to avoid adding the readline
  34. // dependency in the vendored copy of pprof in the Go distribution,
  35. // which does not use this file.
  36. type readlineUI struct {
  37. rl *readline.Instance
  38. }
  39. func newUI() driver.UI {
  40. rl, err := readline.New("")
  41. if err != nil {
  42. fmt.Fprintf(os.Stderr, "readline: %v", err)
  43. return nil
  44. }
  45. return &readlineUI{
  46. rl: rl,
  47. }
  48. }
  49. // ReadLine returns a line of text (a command) read from the user.
  50. // prompt is printed before reading the command.
  51. func (r *readlineUI) ReadLine(prompt string) (string, error) {
  52. r.rl.SetPrompt(prompt)
  53. return r.rl.Readline()
  54. }
  55. // Print shows a message to the user.
  56. // It is printed over stderr as stdout is reserved for regular output.
  57. func (r *readlineUI) Print(args ...interface{}) {
  58. text := fmt.Sprint(args...)
  59. if !strings.HasSuffix(text, "\n") {
  60. text += "\n"
  61. }
  62. fmt.Fprint(r.rl.Stderr(), text)
  63. }
  64. // PrintErr shows a message to the user, colored in red for emphasis.
  65. // It is printed over stderr as stdout is reserved for regular output.
  66. func (r *readlineUI) PrintErr(args ...interface{}) {
  67. text := fmt.Sprint(args...)
  68. if !strings.HasSuffix(text, "\n") {
  69. text += "\n"
  70. }
  71. if readline.IsTerminal(int(syscall.Stderr)) {
  72. text = colorize(text)
  73. }
  74. fmt.Fprint(r.rl.Stderr(), text)
  75. }
  76. // colorize the msg using ANSI color escapes.
  77. func colorize(msg string) string {
  78. var red = 31
  79. var colorEscape = fmt.Sprintf("\033[0;%dm", red)
  80. var colorResetEscape = "\033[0m"
  81. return colorEscape + msg + colorResetEscape
  82. }
  83. // IsTerminal returns whether the UI is known to be tied to an
  84. // interactive terminal (as opposed to being redirected to a file).
  85. func (r *readlineUI) IsTerminal() bool {
  86. return readline.IsTerminal(int(syscall.Stdout))
  87. }
  88. // WantBrowser starts a browser on interactive mode.
  89. func (r *readlineUI) WantBrowser() bool {
  90. return r.IsTerminal()
  91. }
  92. // SetAutoComplete instructs the UI to call complete(cmd) to obtain
  93. // the auto-completion of cmd, if the UI supports auto-completion at all.
  94. func (r *readlineUI) SetAutoComplete(complete func(string) string) {
  95. // TODO: Implement auto-completion support.
  96. }