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.

manager_logging.go 10.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. // Copyright 2022 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package cmd
  5. import (
  6. "fmt"
  7. "net/http"
  8. "os"
  9. "code.gitea.io/gitea/modules/log"
  10. "code.gitea.io/gitea/modules/private"
  11. "github.com/urfave/cli"
  12. )
  13. var (
  14. defaultLoggingFlags = []cli.Flag{
  15. cli.StringFlag{
  16. Name: "group, g",
  17. Usage: "Group to add logger to - will default to \"default\"",
  18. }, cli.StringFlag{
  19. Name: "name, n",
  20. Usage: "Name of the new logger - will default to mode",
  21. }, cli.StringFlag{
  22. Name: "level, l",
  23. Usage: "Logging level for the new logger",
  24. }, cli.StringFlag{
  25. Name: "stacktrace-level, L",
  26. Usage: "Stacktrace logging level",
  27. }, cli.StringFlag{
  28. Name: "flags, F",
  29. Usage: "Flags for the logger",
  30. }, cli.StringFlag{
  31. Name: "expression, e",
  32. Usage: "Matching expression for the logger",
  33. }, cli.StringFlag{
  34. Name: "prefix, p",
  35. Usage: "Prefix for the logger",
  36. }, cli.BoolFlag{
  37. Name: "color",
  38. Usage: "Use color in the logs",
  39. }, cli.BoolFlag{
  40. Name: "debug",
  41. },
  42. }
  43. subcmdLogging = cli.Command{
  44. Name: "logging",
  45. Usage: "Adjust logging commands",
  46. Subcommands: []cli.Command{
  47. {
  48. Name: "pause",
  49. Usage: "Pause logging (Gitea will buffer logs up to a certain point and will drop them after that point)",
  50. Flags: []cli.Flag{
  51. cli.BoolFlag{
  52. Name: "debug",
  53. },
  54. },
  55. Action: runPauseLogging,
  56. }, {
  57. Name: "resume",
  58. Usage: "Resume logging",
  59. Flags: []cli.Flag{
  60. cli.BoolFlag{
  61. Name: "debug",
  62. },
  63. },
  64. Action: runResumeLogging,
  65. }, {
  66. Name: "release-and-reopen",
  67. Usage: "Cause Gitea to release and re-open files used for logging",
  68. Flags: []cli.Flag{
  69. cli.BoolFlag{
  70. Name: "debug",
  71. },
  72. },
  73. Action: runReleaseReopenLogging,
  74. }, {
  75. Name: "remove",
  76. Usage: "Remove a logger",
  77. ArgsUsage: "[name] Name of logger to remove",
  78. Flags: []cli.Flag{
  79. cli.BoolFlag{
  80. Name: "debug",
  81. }, cli.StringFlag{
  82. Name: "group, g",
  83. Usage: "Group to add logger to - will default to \"default\"",
  84. },
  85. },
  86. Action: runRemoveLogger,
  87. }, {
  88. Name: "add",
  89. Usage: "Add a logger",
  90. Subcommands: []cli.Command{
  91. {
  92. Name: "console",
  93. Usage: "Add a console logger",
  94. Flags: append(defaultLoggingFlags,
  95. cli.BoolFlag{
  96. Name: "stderr",
  97. Usage: "Output console logs to stderr - only relevant for console",
  98. }),
  99. Action: runAddConsoleLogger,
  100. }, {
  101. Name: "file",
  102. Usage: "Add a file logger",
  103. Flags: append(defaultLoggingFlags, []cli.Flag{
  104. cli.StringFlag{
  105. Name: "filename, f",
  106. Usage: "Filename for the logger - this must be set.",
  107. }, cli.BoolTFlag{
  108. Name: "rotate, r",
  109. Usage: "Rotate logs",
  110. }, cli.Int64Flag{
  111. Name: "max-size, s",
  112. Usage: "Maximum size in bytes before rotation",
  113. }, cli.BoolTFlag{
  114. Name: "daily, d",
  115. Usage: "Rotate logs daily",
  116. }, cli.IntFlag{
  117. Name: "max-days, D",
  118. Usage: "Maximum number of daily logs to keep",
  119. }, cli.BoolTFlag{
  120. Name: "compress, z",
  121. Usage: "Compress rotated logs",
  122. }, cli.IntFlag{
  123. Name: "compression-level, Z",
  124. Usage: "Compression level to use",
  125. },
  126. }...),
  127. Action: runAddFileLogger,
  128. }, {
  129. Name: "conn",
  130. Usage: "Add a net conn logger",
  131. Flags: append(defaultLoggingFlags, []cli.Flag{
  132. cli.BoolFlag{
  133. Name: "reconnect-on-message, R",
  134. Usage: "Reconnect to host for every message",
  135. }, cli.BoolFlag{
  136. Name: "reconnect, r",
  137. Usage: "Reconnect to host when connection is dropped",
  138. }, cli.StringFlag{
  139. Name: "protocol, P",
  140. Usage: "Set protocol to use: tcp, unix, or udp (defaults to tcp)",
  141. }, cli.StringFlag{
  142. Name: "address, a",
  143. Usage: "Host address and port to connect to (defaults to :7020)",
  144. },
  145. }...),
  146. Action: runAddConnLogger,
  147. }, {
  148. Name: "smtp",
  149. Usage: "Add an SMTP logger",
  150. Flags: append(defaultLoggingFlags, []cli.Flag{
  151. cli.StringFlag{
  152. Name: "username, u",
  153. Usage: "Mail server username",
  154. }, cli.StringFlag{
  155. Name: "password, P",
  156. Usage: "Mail server password",
  157. }, cli.StringFlag{
  158. Name: "host, H",
  159. Usage: "Mail server host (defaults to: 127.0.0.1:25)",
  160. }, cli.StringSliceFlag{
  161. Name: "send-to, s",
  162. Usage: "Email address(es) to send to",
  163. }, cli.StringFlag{
  164. Name: "subject, S",
  165. Usage: "Subject header of sent emails",
  166. },
  167. }...),
  168. Action: runAddSMTPLogger,
  169. },
  170. },
  171. }, {
  172. Name: "log-sql",
  173. Usage: "Set LogSQL",
  174. Flags: []cli.Flag{
  175. cli.BoolFlag{
  176. Name: "debug",
  177. }, cli.BoolFlag{
  178. Name: "off",
  179. Usage: "Switch off SQL logging",
  180. },
  181. },
  182. Action: runSetLogSQL,
  183. },
  184. },
  185. }
  186. )
  187. func runRemoveLogger(c *cli.Context) error {
  188. setup("manager", c.Bool("debug"))
  189. group := c.String("group")
  190. if len(group) == 0 {
  191. group = log.DEFAULT
  192. }
  193. name := c.Args().First()
  194. ctx, cancel := installSignals()
  195. defer cancel()
  196. statusCode, msg := private.RemoveLogger(ctx, group, name)
  197. switch statusCode {
  198. case http.StatusInternalServerError:
  199. return fail("InternalServerError", msg)
  200. }
  201. fmt.Fprintln(os.Stdout, msg)
  202. return nil
  203. }
  204. func runAddSMTPLogger(c *cli.Context) error {
  205. setup("manager", c.Bool("debug"))
  206. vals := map[string]interface{}{}
  207. mode := "smtp"
  208. if c.IsSet("host") {
  209. vals["host"] = c.String("host")
  210. } else {
  211. vals["host"] = "127.0.0.1:25"
  212. }
  213. if c.IsSet("username") {
  214. vals["username"] = c.String("username")
  215. }
  216. if c.IsSet("password") {
  217. vals["password"] = c.String("password")
  218. }
  219. if !c.IsSet("send-to") {
  220. return fmt.Errorf("Some recipients must be provided")
  221. }
  222. vals["sendTos"] = c.StringSlice("send-to")
  223. if c.IsSet("subject") {
  224. vals["subject"] = c.String("subject")
  225. } else {
  226. vals["subject"] = "Diagnostic message from Gitea"
  227. }
  228. return commonAddLogger(c, mode, vals)
  229. }
  230. func runAddConnLogger(c *cli.Context) error {
  231. setup("manager", c.Bool("debug"))
  232. vals := map[string]interface{}{}
  233. mode := "conn"
  234. vals["net"] = "tcp"
  235. if c.IsSet("protocol") {
  236. switch c.String("protocol") {
  237. case "udp":
  238. vals["net"] = "udp"
  239. case "unix":
  240. vals["net"] = "unix"
  241. }
  242. }
  243. if c.IsSet("address") {
  244. vals["address"] = c.String("address")
  245. } else {
  246. vals["address"] = ":7020"
  247. }
  248. if c.IsSet("reconnect") {
  249. vals["reconnect"] = c.Bool("reconnect")
  250. }
  251. if c.IsSet("reconnect-on-message") {
  252. vals["reconnectOnMsg"] = c.Bool("reconnect-on-message")
  253. }
  254. return commonAddLogger(c, mode, vals)
  255. }
  256. func runAddFileLogger(c *cli.Context) error {
  257. setup("manager", c.Bool("debug"))
  258. vals := map[string]interface{}{}
  259. mode := "file"
  260. if c.IsSet("filename") {
  261. vals["filename"] = c.String("filename")
  262. } else {
  263. return fmt.Errorf("filename must be set when creating a file logger")
  264. }
  265. if c.IsSet("rotate") {
  266. vals["rotate"] = c.Bool("rotate")
  267. }
  268. if c.IsSet("max-size") {
  269. vals["maxsize"] = c.Int64("max-size")
  270. }
  271. if c.IsSet("daily") {
  272. vals["daily"] = c.Bool("daily")
  273. }
  274. if c.IsSet("max-days") {
  275. vals["maxdays"] = c.Int("max-days")
  276. }
  277. if c.IsSet("compress") {
  278. vals["compress"] = c.Bool("compress")
  279. }
  280. if c.IsSet("compression-level") {
  281. vals["compressionLevel"] = c.Int("compression-level")
  282. }
  283. return commonAddLogger(c, mode, vals)
  284. }
  285. func runAddConsoleLogger(c *cli.Context) error {
  286. setup("manager", c.Bool("debug"))
  287. vals := map[string]interface{}{}
  288. mode := "console"
  289. if c.IsSet("stderr") && c.Bool("stderr") {
  290. vals["stderr"] = c.Bool("stderr")
  291. }
  292. return commonAddLogger(c, mode, vals)
  293. }
  294. func commonAddLogger(c *cli.Context, mode string, vals map[string]interface{}) error {
  295. if len(c.String("level")) > 0 {
  296. vals["level"] = log.FromString(c.String("level")).String()
  297. }
  298. if len(c.String("stacktrace-level")) > 0 {
  299. vals["stacktraceLevel"] = log.FromString(c.String("stacktrace-level")).String()
  300. }
  301. if len(c.String("expression")) > 0 {
  302. vals["expression"] = c.String("expression")
  303. }
  304. if len(c.String("prefix")) > 0 {
  305. vals["prefix"] = c.String("prefix")
  306. }
  307. if len(c.String("flags")) > 0 {
  308. vals["flags"] = log.FlagsFromString(c.String("flags"))
  309. }
  310. if c.IsSet("color") {
  311. vals["colorize"] = c.Bool("color")
  312. }
  313. group := "default"
  314. if c.IsSet("group") {
  315. group = c.String("group")
  316. }
  317. name := mode
  318. if c.IsSet("name") {
  319. name = c.String("name")
  320. }
  321. ctx, cancel := installSignals()
  322. defer cancel()
  323. statusCode, msg := private.AddLogger(ctx, group, name, mode, vals)
  324. switch statusCode {
  325. case http.StatusInternalServerError:
  326. return fail("InternalServerError", msg)
  327. }
  328. fmt.Fprintln(os.Stdout, msg)
  329. return nil
  330. }
  331. func runPauseLogging(c *cli.Context) error {
  332. ctx, cancel := installSignals()
  333. defer cancel()
  334. setup("manager", c.Bool("debug"))
  335. statusCode, msg := private.PauseLogging(ctx)
  336. switch statusCode {
  337. case http.StatusInternalServerError:
  338. return fail("InternalServerError", msg)
  339. }
  340. fmt.Fprintln(os.Stdout, msg)
  341. return nil
  342. }
  343. func runResumeLogging(c *cli.Context) error {
  344. ctx, cancel := installSignals()
  345. defer cancel()
  346. setup("manager", c.Bool("debug"))
  347. statusCode, msg := private.ResumeLogging(ctx)
  348. switch statusCode {
  349. case http.StatusInternalServerError:
  350. return fail("InternalServerError", msg)
  351. }
  352. fmt.Fprintln(os.Stdout, msg)
  353. return nil
  354. }
  355. func runReleaseReopenLogging(c *cli.Context) error {
  356. ctx, cancel := installSignals()
  357. defer cancel()
  358. setup("manager", c.Bool("debug"))
  359. statusCode, msg := private.ReleaseReopenLogging(ctx)
  360. switch statusCode {
  361. case http.StatusInternalServerError:
  362. return fail("InternalServerError", msg)
  363. }
  364. fmt.Fprintln(os.Stdout, msg)
  365. return nil
  366. }
  367. func runSetLogSQL(c *cli.Context) error {
  368. ctx, cancel := installSignals()
  369. defer cancel()
  370. setup("manager", c.Bool("debug"))
  371. statusCode, msg := private.SetLogSQL(ctx, !c.Bool("off"))
  372. switch statusCode {
  373. case http.StatusInternalServerError:
  374. return fail("InternalServerError", msg)
  375. }
  376. fmt.Fprintln(os.Stdout, msg)
  377. return nil
  378. }