gitea源码

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. // Copyright 2022 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package cmd
  4. import (
  5. "context"
  6. "errors"
  7. "fmt"
  8. "os"
  9. "code.gitea.io/gitea/modules/log"
  10. "code.gitea.io/gitea/modules/private"
  11. "github.com/urfave/cli/v3"
  12. )
  13. var (
  14. defaultLoggingFlags = []cli.Flag{
  15. &cli.StringFlag{
  16. Name: "logger",
  17. Usage: `Logger name - will default to "default"`,
  18. },
  19. &cli.StringFlag{
  20. Name: "writer",
  21. Usage: "Name of the log writer - will default to mode",
  22. },
  23. &cli.StringFlag{
  24. Name: "level",
  25. Usage: "Logging level for the new logger",
  26. },
  27. &cli.StringFlag{
  28. Name: "stacktrace-level",
  29. Aliases: []string{"L"},
  30. Usage: "Stacktrace logging level",
  31. },
  32. &cli.StringFlag{
  33. Name: "flags",
  34. Aliases: []string{"F"},
  35. Usage: "Flags for the logger",
  36. },
  37. &cli.StringFlag{
  38. Name: "expression",
  39. Aliases: []string{"e"},
  40. Usage: "Matching expression for the logger",
  41. },
  42. &cli.StringFlag{
  43. Name: "prefix",
  44. Aliases: []string{"p"},
  45. Usage: "Prefix for the logger",
  46. },
  47. &cli.BoolFlag{
  48. Name: "color",
  49. Usage: "Use color in the logs",
  50. },
  51. &cli.BoolFlag{
  52. Name: "debug",
  53. },
  54. }
  55. subcmdLogging = &cli.Command{
  56. Name: "logging",
  57. Usage: "Adjust logging commands",
  58. Commands: []*cli.Command{
  59. {
  60. Name: "pause",
  61. Usage: "Pause logging (Gitea will buffer logs up to a certain point and will drop them after that point)",
  62. Flags: []cli.Flag{
  63. &cli.BoolFlag{
  64. Name: "debug",
  65. },
  66. },
  67. Action: runPauseLogging,
  68. }, {
  69. Name: "resume",
  70. Usage: "Resume logging",
  71. Flags: []cli.Flag{
  72. &cli.BoolFlag{
  73. Name: "debug",
  74. },
  75. },
  76. Action: runResumeLogging,
  77. }, {
  78. Name: "release-and-reopen",
  79. Usage: "Cause Gitea to release and re-open files used for logging",
  80. Flags: []cli.Flag{
  81. &cli.BoolFlag{
  82. Name: "debug",
  83. },
  84. },
  85. Action: runReleaseReopenLogging,
  86. }, {
  87. Name: "remove",
  88. Usage: "Remove a logger",
  89. ArgsUsage: "[name] Name of logger to remove",
  90. Flags: []cli.Flag{
  91. &cli.BoolFlag{
  92. Name: "debug",
  93. }, &cli.StringFlag{
  94. Name: "logger",
  95. Usage: `Logger name - will default to "default"`,
  96. },
  97. },
  98. Action: runRemoveLogger,
  99. }, {
  100. Name: "add",
  101. Usage: "Add a logger",
  102. Commands: []*cli.Command{
  103. {
  104. Name: "file",
  105. Usage: "Add a file logger",
  106. Flags: append(defaultLoggingFlags, []cli.Flag{
  107. &cli.StringFlag{
  108. Name: "filename",
  109. Aliases: []string{"f"},
  110. Usage: "Filename for the logger - this must be set.",
  111. },
  112. &cli.BoolFlag{
  113. Name: "rotate",
  114. Aliases: []string{"r"},
  115. Usage: "Rotate logs",
  116. },
  117. &cli.Int64Flag{
  118. Name: "max-size",
  119. Aliases: []string{"s"},
  120. Usage: "Maximum size in bytes before rotation",
  121. },
  122. &cli.BoolFlag{
  123. Name: "daily",
  124. Aliases: []string{"d"},
  125. Usage: "Rotate logs daily",
  126. },
  127. &cli.IntFlag{
  128. Name: "max-days",
  129. Aliases: []string{"D"},
  130. Usage: "Maximum number of daily logs to keep",
  131. },
  132. &cli.BoolFlag{
  133. Name: "compress",
  134. Aliases: []string{"z"},
  135. Usage: "Compress rotated logs",
  136. },
  137. &cli.IntFlag{
  138. Name: "compression-level",
  139. Aliases: []string{"Z"},
  140. Usage: "Compression level to use",
  141. },
  142. }...),
  143. Action: runAddFileLogger,
  144. }, {
  145. Name: "conn",
  146. Usage: "Add a net conn logger",
  147. Flags: append(defaultLoggingFlags, []cli.Flag{
  148. &cli.BoolFlag{
  149. Name: "reconnect-on-message",
  150. Aliases: []string{"R"},
  151. Usage: "Reconnect to host for every message",
  152. },
  153. &cli.BoolFlag{
  154. Name: "reconnect",
  155. Aliases: []string{"r"},
  156. Usage: "Reconnect to host when connection is dropped",
  157. },
  158. &cli.StringFlag{
  159. Name: "protocol",
  160. Aliases: []string{"P"},
  161. Usage: "Set protocol to use: tcp, unix, or udp (defaults to tcp)",
  162. },
  163. &cli.StringFlag{
  164. Name: "address",
  165. Aliases: []string{"a"},
  166. Usage: "Host address and port to connect to (defaults to :7020)",
  167. },
  168. }...),
  169. Action: runAddConnLogger,
  170. },
  171. },
  172. }, {
  173. Name: "log-sql",
  174. Usage: "Set LogSQL",
  175. Flags: []cli.Flag{
  176. &cli.BoolFlag{
  177. Name: "debug",
  178. },
  179. &cli.BoolFlag{
  180. Name: "off",
  181. Usage: "Switch off SQL logging",
  182. },
  183. },
  184. Action: runSetLogSQL,
  185. },
  186. },
  187. }
  188. )
  189. func runRemoveLogger(ctx context.Context, c *cli.Command) error {
  190. setup(ctx, c.Bool("debug"))
  191. logger := c.String("logger")
  192. if len(logger) == 0 {
  193. logger = log.DEFAULT
  194. }
  195. writer := c.Args().First()
  196. extra := private.RemoveLogger(ctx, logger, writer)
  197. return handleCliResponseExtra(extra)
  198. }
  199. func runAddConnLogger(ctx context.Context, c *cli.Command) error {
  200. setup(ctx, c.Bool("debug"))
  201. vals := map[string]any{}
  202. mode := "conn"
  203. vals["net"] = "tcp"
  204. if c.IsSet("protocol") {
  205. switch c.String("protocol") {
  206. case "udp":
  207. vals["net"] = "udp"
  208. case "unix":
  209. vals["net"] = "unix"
  210. }
  211. }
  212. if c.IsSet("address") {
  213. vals["address"] = c.String("address")
  214. } else {
  215. vals["address"] = ":7020"
  216. }
  217. if c.IsSet("reconnect") {
  218. vals["reconnect"] = c.Bool("reconnect")
  219. }
  220. if c.IsSet("reconnect-on-message") {
  221. vals["reconnectOnMsg"] = c.Bool("reconnect-on-message")
  222. }
  223. return commonAddLogger(ctx, c, mode, vals)
  224. }
  225. func runAddFileLogger(ctx context.Context, c *cli.Command) error {
  226. setup(ctx, c.Bool("debug"))
  227. vals := map[string]any{}
  228. mode := "file"
  229. if c.IsSet("filename") {
  230. vals["filename"] = c.String("filename")
  231. } else {
  232. return errors.New("filename must be set when creating a file logger")
  233. }
  234. if c.IsSet("rotate") {
  235. vals["rotate"] = c.Bool("rotate")
  236. }
  237. if c.IsSet("max-size") {
  238. vals["maxsize"] = c.Int64("max-size")
  239. }
  240. if c.IsSet("daily") {
  241. vals["daily"] = c.Bool("daily")
  242. }
  243. if c.IsSet("max-days") {
  244. vals["maxdays"] = c.Int("max-days")
  245. }
  246. if c.IsSet("compress") {
  247. vals["compress"] = c.Bool("compress")
  248. }
  249. if c.IsSet("compression-level") {
  250. vals["compressionLevel"] = c.Int("compression-level")
  251. }
  252. return commonAddLogger(ctx, c, mode, vals)
  253. }
  254. func commonAddLogger(ctx context.Context, c *cli.Command, mode string, vals map[string]any) error {
  255. if len(c.String("level")) > 0 {
  256. vals["level"] = log.LevelFromString(c.String("level")).String()
  257. }
  258. if len(c.String("stacktrace-level")) > 0 {
  259. vals["stacktraceLevel"] = log.LevelFromString(c.String("stacktrace-level")).String()
  260. }
  261. if len(c.String("expression")) > 0 {
  262. vals["expression"] = c.String("expression")
  263. }
  264. if len(c.String("prefix")) > 0 {
  265. vals["prefix"] = c.String("prefix")
  266. }
  267. if len(c.String("flags")) > 0 {
  268. vals["flags"] = log.FlagsFromString(c.String("flags"))
  269. }
  270. if c.IsSet("color") {
  271. vals["colorize"] = c.Bool("color")
  272. }
  273. logger := log.DEFAULT
  274. if c.IsSet("logger") {
  275. logger = c.String("logger")
  276. }
  277. writer := mode
  278. if c.IsSet("writer") {
  279. writer = c.String("writer")
  280. }
  281. extra := private.AddLogger(ctx, logger, writer, mode, vals)
  282. return handleCliResponseExtra(extra)
  283. }
  284. func runPauseLogging(ctx context.Context, c *cli.Command) error {
  285. setup(ctx, c.Bool("debug"))
  286. userMsg := private.PauseLogging(ctx)
  287. _, _ = fmt.Fprintln(os.Stdout, userMsg)
  288. return nil
  289. }
  290. func runResumeLogging(ctx context.Context, c *cli.Command) error {
  291. setup(ctx, c.Bool("debug"))
  292. userMsg := private.ResumeLogging(ctx)
  293. _, _ = fmt.Fprintln(os.Stdout, userMsg)
  294. return nil
  295. }
  296. func runReleaseReopenLogging(ctx context.Context, c *cli.Command) error {
  297. setup(ctx, c.Bool("debug"))
  298. userMsg := private.ReleaseReopenLogging(ctx)
  299. _, _ = fmt.Fprintln(os.Stdout, userMsg)
  300. return nil
  301. }
  302. func runSetLogSQL(ctx context.Context, c *cli.Command) error {
  303. setup(ctx, c.Bool("debug"))
  304. extra := private.SetLogSQL(ctx, !c.Bool("off"))
  305. return handleCliResponseExtra(extra)
  306. }