PageRenderTime 49ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/Godeps/_workspace/src/github.com/golang/glog/glog.go

https://github.com/vmarmol/cadvisor
Go | 1034 lines | 647 code | 104 blank | 283 comment | 122 complexity | 56c44441405244ee6da991db2cf67fce MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause
  1. // Go support for leveled logs, analogous to https://code.google.com/p/google-glog/
  2. //
  3. // Copyright 2013 Google Inc. All Rights Reserved.
  4. //
  5. // Licensed under the Apache License, Version 2.0 (the "License");
  6. // you may not use this file except in compliance with the License.
  7. // You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing, software
  12. // distributed under the License is distributed on an "AS IS" BASIS,
  13. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. // See the License for the specific language governing permissions and
  15. // limitations under the License.
  16. // Package glog implements logging analogous to the Google-internal C++ INFO/ERROR/V setup.
  17. // It provides functions Info, Warning, Error, Fatal, plus formatting variants such as
  18. // Infof. It also provides V-style logging controlled by the -v and -vmodule=file=2 flags.
  19. //
  20. // Basic examples:
  21. //
  22. // glog.Info("Prepare to repel boarders")
  23. //
  24. // glog.Fatalf("Initialization failed: %s", err)
  25. //
  26. // See the documentation for the V function for an explanation of these examples:
  27. //
  28. // if glog.V(2) {
  29. // glog.Info("Starting transaction...")
  30. // }
  31. //
  32. // glog.V(2).Infoln("Processed", nItems, "elements")
  33. //
  34. // Log output is buffered and written periodically using Flush. Programs
  35. // should call Flush before exiting to guarantee all log output is written.
  36. //
  37. // By default, all log statements write to files in a temporary directory.
  38. // This package provides several flags that modify this behavior.
  39. // As a result, flag.Parse must be called before any logging is done.
  40. //
  41. // -logtostderr=false
  42. // Logs are written to standard error instead of to files.
  43. // -alsologtostderr=false
  44. // Logs are written to standard error as well as to files.
  45. // -stderrthreshold=ERROR
  46. // Log events at or above this severity are logged to standard
  47. // error as well as to files.
  48. // -log_dir=""
  49. // Log files will be written to this directory instead of the
  50. // default temporary directory.
  51. //
  52. // Other flags provide aids to debugging.
  53. //
  54. // -log_backtrace_at=""
  55. // When set to a file and line number holding a logging statement,
  56. // such as
  57. // -log_backtrace_at=gopherflakes.go:234
  58. // a stack trace will be written to the Info log whenever execution
  59. // hits that statement. (Unlike with -vmodule, the ".go" must be
  60. // present.)
  61. // -v=0
  62. // Enable V-leveled logging at the specified level.
  63. // -vmodule=""
  64. // The syntax of the argument is a comma-separated list of pattern=N,
  65. // where pattern is a literal file name (minus the ".go" suffix) or
  66. // "glob" pattern and N is a V level. For instance,
  67. // -vmodule=gopher*=3
  68. // sets the V level to 3 in all Go files whose names begin "gopher".
  69. //
  70. package glog
  71. import (
  72. "bufio"
  73. "bytes"
  74. "errors"
  75. "flag"
  76. "fmt"
  77. "io"
  78. "os"
  79. "path/filepath"
  80. "runtime"
  81. "strconv"
  82. "strings"
  83. "sync"
  84. "sync/atomic"
  85. "time"
  86. )
  87. // severity identifies the sort of log: info, warning etc. It also implements
  88. // the flag.Value interface. The -stderrthreshold flag is of type severity and
  89. // should be modified only through the flag.Value interface. The values match
  90. // the corresponding constants in C++.
  91. type severity int32 // sync/atomic int32
  92. const (
  93. infoLog severity = iota
  94. warningLog
  95. errorLog
  96. fatalLog
  97. numSeverity = 4
  98. )
  99. const severityChar = "IWEF"
  100. var severityName = []string{
  101. infoLog: "INFO",
  102. warningLog: "WARNING",
  103. errorLog: "ERROR",
  104. fatalLog: "FATAL",
  105. }
  106. // get returns the value of the severity.
  107. func (s *severity) get() severity {
  108. return severity(atomic.LoadInt32((*int32)(s)))
  109. }
  110. // set sets the value of the severity.
  111. func (s *severity) set(val severity) {
  112. atomic.StoreInt32((*int32)(s), int32(val))
  113. }
  114. // String is part of the flag.Value interface.
  115. func (s *severity) String() string {
  116. return strconv.FormatInt(int64(*s), 10)
  117. }
  118. // Get is part of the flag.Value interface.
  119. func (s *severity) Get() interface{} {
  120. return *s
  121. }
  122. // Set is part of the flag.Value interface.
  123. func (s *severity) Set(value string) error {
  124. var threshold severity
  125. // Is it a known name?
  126. if v, ok := severityByName(value); ok {
  127. threshold = v
  128. } else {
  129. v, err := strconv.Atoi(value)
  130. if err != nil {
  131. return err
  132. }
  133. threshold = severity(v)
  134. }
  135. logging.stderrThreshold.set(threshold)
  136. return nil
  137. }
  138. func severityByName(s string) (severity, bool) {
  139. s = strings.ToUpper(s)
  140. for i, name := range severityName {
  141. if name == s {
  142. return severity(i), true
  143. }
  144. }
  145. return 0, false
  146. }
  147. // OutputStats tracks the number of output lines and bytes written.
  148. type OutputStats struct {
  149. lines int64
  150. bytes int64
  151. }
  152. // Lines returns the number of lines written.
  153. func (s *OutputStats) Lines() int64 {
  154. return atomic.LoadInt64(&s.lines)
  155. }
  156. // Bytes returns the number of bytes written.
  157. func (s *OutputStats) Bytes() int64 {
  158. return atomic.LoadInt64(&s.bytes)
  159. }
  160. // Stats tracks the number of lines of output and number of bytes
  161. // per severity level. Values must be read with atomic.LoadInt64.
  162. var Stats struct {
  163. Info, Warning, Error OutputStats
  164. }
  165. var severityStats = [numSeverity]*OutputStats{
  166. infoLog: &Stats.Info,
  167. warningLog: &Stats.Warning,
  168. errorLog: &Stats.Error,
  169. }
  170. // Level is exported because it appears in the arguments to V and is
  171. // the type of the v flag, which can be set programmatically.
  172. // It's a distinct type because we want to discriminate it from logType.
  173. // Variables of type level are only changed under logging.mu.
  174. // The -v flag is read only with atomic ops, so the state of the logging
  175. // module is consistent.
  176. // Level is treated as a sync/atomic int32.
  177. // Level specifies a level of verbosity for V logs. *Level implements
  178. // flag.Value; the -v flag is of type Level and should be modified
  179. // only through the flag.Value interface.
  180. type Level int32
  181. // get returns the value of the Level.
  182. func (l *Level) get() Level {
  183. return Level(atomic.LoadInt32((*int32)(l)))
  184. }
  185. // set sets the value of the Level.
  186. func (l *Level) set(val Level) {
  187. atomic.StoreInt32((*int32)(l), int32(val))
  188. }
  189. // String is part of the flag.Value interface.
  190. func (l *Level) String() string {
  191. return strconv.FormatInt(int64(*l), 10)
  192. }
  193. // Get is part of the flag.Value interface.
  194. func (l *Level) Get() interface{} {
  195. return *l
  196. }
  197. // Set is part of the flag.Value interface.
  198. func (l *Level) Set(value string) error {
  199. v, err := strconv.Atoi(value)
  200. if err != nil {
  201. return err
  202. }
  203. logging.mu.Lock()
  204. defer logging.mu.Unlock()
  205. logging.setVState(Level(v), logging.vmodule.filter, false)
  206. return nil
  207. }
  208. // moduleSpec represents the setting of the -vmodule flag.
  209. type moduleSpec struct {
  210. filter []modulePat
  211. }
  212. // modulePat contains a filter for the -vmodule flag.
  213. // It holds a verbosity level and a file pattern to match.
  214. type modulePat struct {
  215. pattern string
  216. literal bool // The pattern is a literal string
  217. level Level
  218. }
  219. // match reports whether the file matches the pattern. It uses a string
  220. // comparison if the pattern contains no metacharacters.
  221. func (m *modulePat) match(file string) bool {
  222. if m.literal {
  223. return file == m.pattern
  224. }
  225. match, _ := filepath.Match(m.pattern, file)
  226. return match
  227. }
  228. func (m *moduleSpec) String() string {
  229. // Lock because the type is not atomic. TODO: clean this up.
  230. logging.mu.Lock()
  231. defer logging.mu.Unlock()
  232. var b bytes.Buffer
  233. for i, f := range m.filter {
  234. if i > 0 {
  235. b.WriteRune(',')
  236. }
  237. fmt.Fprintf(&b, "%s=%d", f.pattern, f.level)
  238. }
  239. return b.String()
  240. }
  241. // Get is part of the (Go 1.2) flag.Getter interface. It always returns nil for this flag type since the
  242. // struct is not exported.
  243. func (m *moduleSpec) Get() interface{} {
  244. return nil
  245. }
  246. var errVmoduleSyntax = errors.New("syntax error: expect comma-separated list of filename=N")
  247. // Syntax: -vmodule=recordio=2,file=1,gfs*=3
  248. func (m *moduleSpec) Set(value string) error {
  249. var filter []modulePat
  250. for _, pat := range strings.Split(value, ",") {
  251. if len(pat) == 0 {
  252. // Empty strings such as from a trailing comma can be ignored.
  253. continue
  254. }
  255. patLev := strings.Split(pat, "=")
  256. if len(patLev) != 2 || len(patLev[0]) == 0 || len(patLev[1]) == 0 {
  257. return errVmoduleSyntax
  258. }
  259. pattern := patLev[0]
  260. v, err := strconv.Atoi(patLev[1])
  261. if err != nil {
  262. return errors.New("syntax error: expect comma-separated list of filename=N")
  263. }
  264. if v < 0 {
  265. return errors.New("negative value for vmodule level")
  266. }
  267. if v == 0 {
  268. continue // Ignore. It's harmless but no point in paying the overhead.
  269. }
  270. // TODO: check syntax of filter?
  271. filter = append(filter, modulePat{pattern, isLiteral(pattern), Level(v)})
  272. }
  273. logging.mu.Lock()
  274. defer logging.mu.Unlock()
  275. logging.setVState(logging.verbosity, filter, true)
  276. return nil
  277. }
  278. // isLiteral reports whether the pattern is a literal string, that is, has no metacharacters
  279. // that require filepath.Match to be called to match the pattern.
  280. func isLiteral(pattern string) bool {
  281. return !strings.ContainsAny(pattern, `*?[]\`)
  282. }
  283. // traceLocation represents the setting of the -log_backtrace_at flag.
  284. type traceLocation struct {
  285. file string
  286. line int
  287. }
  288. // isSet reports whether the trace location has been specified.
  289. // logging.mu is held.
  290. func (t *traceLocation) isSet() bool {
  291. return t.line > 0
  292. }
  293. // match reports whether the specified file and line matches the trace location.
  294. // The argument file name is the full path, not the basename specified in the flag.
  295. // logging.mu is held.
  296. func (t *traceLocation) match(file string, line int) bool {
  297. if t.line != line {
  298. return false
  299. }
  300. if i := strings.LastIndex(file, "/"); i >= 0 {
  301. file = file[i+1:]
  302. }
  303. return t.file == file
  304. }
  305. func (t *traceLocation) String() string {
  306. // Lock because the type is not atomic. TODO: clean this up.
  307. logging.mu.Lock()
  308. defer logging.mu.Unlock()
  309. return fmt.Sprintf("%s:%d", t.file, t.line)
  310. }
  311. // Get is part of the (Go 1.2) flag.Getter interface. It always returns nil for this flag type since the
  312. // struct is not exported
  313. func (t *traceLocation) Get() interface{} {
  314. return nil
  315. }
  316. var errTraceSyntax = errors.New("syntax error: expect file.go:234")
  317. // Syntax: -log_backtrace_at=gopherflakes.go:234
  318. // Note that unlike vmodule the file extension is included here.
  319. func (t *traceLocation) Set(value string) error {
  320. if value == "" {
  321. // Unset.
  322. t.line = 0
  323. t.file = ""
  324. }
  325. fields := strings.Split(value, ":")
  326. if len(fields) != 2 {
  327. return errTraceSyntax
  328. }
  329. file, line := fields[0], fields[1]
  330. if !strings.Contains(file, ".") {
  331. return errTraceSyntax
  332. }
  333. v, err := strconv.Atoi(line)
  334. if err != nil {
  335. return errTraceSyntax
  336. }
  337. if v <= 0 {
  338. return errors.New("negative or zero value for level")
  339. }
  340. logging.mu.Lock()
  341. defer logging.mu.Unlock()
  342. t.line = v
  343. t.file = file
  344. return nil
  345. }
  346. // flushSyncWriter is the interface satisfied by logging destinations.
  347. type flushSyncWriter interface {
  348. Flush() error
  349. Sync() error
  350. io.Writer
  351. }
  352. func init() {
  353. flag.BoolVar(&logging.toStderr, "logtostderr", false, "log to standard error instead of files")
  354. flag.BoolVar(&logging.alsoToStderr, "alsologtostderr", false, "log to standard error as well as files")
  355. flag.Var(&logging.verbosity, "v", "log level for V logs")
  356. flag.Var(&logging.stderrThreshold, "stderrthreshold", "logs at or above this threshold go to stderr")
  357. flag.Var(&logging.vmodule, "vmodule", "comma-separated list of pattern=N settings for file-filtered logging")
  358. flag.Var(&logging.traceLocation, "log_backtrace_at", "when logging hits line file:N, emit a stack trace")
  359. // Default stderrThreshold is ERROR.
  360. logging.stderrThreshold = errorLog
  361. logging.setVState(0, nil, false)
  362. go logging.flushDaemon()
  363. }
  364. // Flush flushes all pending log I/O.
  365. func Flush() {
  366. logging.lockAndFlushAll()
  367. }
  368. // loggingT collects all the global state of the logging setup.
  369. type loggingT struct {
  370. // Boolean flags. Not handled atomically because the flag.Value interface
  371. // does not let us avoid the =true, and that shorthand is necessary for
  372. // compatibility. TODO: does this matter enough to fix? Seems unlikely.
  373. toStderr bool // The -logtostderr flag.
  374. alsoToStderr bool // The -alsologtostderr flag.
  375. // Level flag. Handled atomically.
  376. stderrThreshold severity // The -stderrthreshold flag.
  377. // freeList is a list of byte buffers, maintained under freeListMu.
  378. freeList *buffer
  379. // freeListMu maintains the free list. It is separate from the main mutex
  380. // so buffers can be grabbed and printed to without holding the main lock,
  381. // for better parallelization.
  382. freeListMu sync.Mutex
  383. // mu protects the remaining elements of this structure and is
  384. // used to synchronize logging.
  385. mu sync.Mutex
  386. // file holds writer for each of the log types.
  387. file [numSeverity]flushSyncWriter
  388. // pcs is used in V to avoid an allocation when computing the caller's PC.
  389. pcs [1]uintptr
  390. // vmap is a cache of the V Level for each V() call site, identified by PC.
  391. // It is wiped whenever the vmodule flag changes state.
  392. vmap map[uintptr]Level
  393. // filterLength stores the length of the vmodule filter chain. If greater
  394. // than zero, it means vmodule is enabled. It may be read safely
  395. // using sync.LoadInt32, but is only modified under mu.
  396. filterLength int32
  397. // traceLocation is the state of the -log_backtrace_at flag.
  398. traceLocation traceLocation
  399. // These flags are modified only under lock, although verbosity may be fetched
  400. // safely using atomic.LoadInt32.
  401. vmodule moduleSpec // The state of the -vmodule flag.
  402. verbosity Level // V logging level, the value of the -v flag/
  403. }
  404. // buffer holds a byte Buffer for reuse. The zero value is ready for use.
  405. type buffer struct {
  406. bytes.Buffer
  407. tmp [64]byte // temporary byte array for creating headers.
  408. next *buffer
  409. }
  410. var logging loggingT
  411. // setVState sets a consistent state for V logging.
  412. // l.mu is held.
  413. func (l *loggingT) setVState(verbosity Level, filter []modulePat, setFilter bool) {
  414. // Turn verbosity off so V will not fire while we are in transition.
  415. logging.verbosity.set(0)
  416. // Ditto for filter length.
  417. logging.filterLength = 0
  418. // Set the new filters and wipe the pc->Level map if the filter has changed.
  419. if setFilter {
  420. logging.vmodule.filter = filter
  421. logging.vmap = make(map[uintptr]Level)
  422. }
  423. // Things are consistent now, so enable filtering and verbosity.
  424. // They are enabled in order opposite to that in V.
  425. atomic.StoreInt32(&logging.filterLength, int32(len(filter)))
  426. logging.verbosity.set(verbosity)
  427. }
  428. // getBuffer returns a new, ready-to-use buffer.
  429. func (l *loggingT) getBuffer() *buffer {
  430. l.freeListMu.Lock()
  431. b := l.freeList
  432. if b != nil {
  433. l.freeList = b.next
  434. }
  435. l.freeListMu.Unlock()
  436. if b == nil {
  437. b = new(buffer)
  438. } else {
  439. b.next = nil
  440. b.Reset()
  441. }
  442. return b
  443. }
  444. // putBuffer returns a buffer to the free list.
  445. func (l *loggingT) putBuffer(b *buffer) {
  446. if b.Len() >= 256 {
  447. // Let big buffers die a natural death.
  448. return
  449. }
  450. l.freeListMu.Lock()
  451. b.next = l.freeList
  452. l.freeList = b
  453. l.freeListMu.Unlock()
  454. }
  455. var timeNow = time.Now // Stubbed out for testing.
  456. /*
  457. header formats a log header as defined by the C++ implementation.
  458. It returns a buffer containing the formatted header.
  459. Log lines have this form:
  460. Lmmdd hh:mm:ss.uuuuuu threadid file:line] msg...
  461. where the fields are defined as follows:
  462. L A single character, representing the log level (eg 'I' for INFO)
  463. mm The month (zero padded; ie May is '05')
  464. dd The day (zero padded)
  465. hh:mm:ss.uuuuuu Time in hours, minutes and fractional seconds
  466. threadid The space-padded thread ID as returned by GetTID()
  467. file The file name
  468. line The line number
  469. msg The user-supplied message
  470. */
  471. func (l *loggingT) header(s severity) *buffer {
  472. // Lmmdd hh:mm:ss.uuuuuu threadid file:line]
  473. now := timeNow()
  474. _, file, line, ok := runtime.Caller(3) // It's always the same number of frames to the user's call.
  475. if !ok {
  476. file = "???"
  477. line = 1
  478. } else {
  479. slash := strings.LastIndex(file, "/")
  480. if slash >= 0 {
  481. file = file[slash+1:]
  482. }
  483. }
  484. if line < 0 {
  485. line = 0 // not a real line number, but acceptable to someDigits
  486. }
  487. if s > fatalLog {
  488. s = infoLog // for safety.
  489. }
  490. buf := l.getBuffer()
  491. // Avoid Fprintf, for speed. The format is so simple that we can do it quickly by hand.
  492. // It's worth about 3X. Fprintf is hard.
  493. _, month, day := now.Date()
  494. hour, minute, second := now.Clock()
  495. buf.tmp[0] = severityChar[s]
  496. buf.twoDigits(1, int(month))
  497. buf.twoDigits(3, day)
  498. buf.tmp[5] = ' '
  499. buf.twoDigits(6, hour)
  500. buf.tmp[8] = ':'
  501. buf.twoDigits(9, minute)
  502. buf.tmp[11] = ':'
  503. buf.twoDigits(12, second)
  504. buf.tmp[14] = '.'
  505. buf.nDigits(6, 15, now.Nanosecond()/1000)
  506. buf.tmp[21] = ' '
  507. buf.nDigits(5, 22, pid) // TODO: should be TID
  508. buf.tmp[27] = ' '
  509. buf.Write(buf.tmp[:28])
  510. buf.WriteString(file)
  511. buf.tmp[0] = ':'
  512. n := buf.someDigits(1, line)
  513. buf.tmp[n+1] = ']'
  514. buf.tmp[n+2] = ' '
  515. buf.Write(buf.tmp[:n+3])
  516. return buf
  517. }
  518. // Some custom tiny helper functions to print the log header efficiently.
  519. const digits = "0123456789"
  520. // twoDigits formats a zero-prefixed two-digit integer at buf.tmp[i].
  521. func (buf *buffer) twoDigits(i, d int) {
  522. buf.tmp[i+1] = digits[d%10]
  523. d /= 10
  524. buf.tmp[i] = digits[d%10]
  525. }
  526. // nDigits formats a zero-prefixed n-digit integer at buf.tmp[i].
  527. func (buf *buffer) nDigits(n, i, d int) {
  528. for j := n - 1; j >= 0; j-- {
  529. buf.tmp[i+j] = digits[d%10]
  530. d /= 10
  531. }
  532. }
  533. // someDigits formats a zero-prefixed variable-width integer at buf.tmp[i].
  534. func (buf *buffer) someDigits(i, d int) int {
  535. // Print into the top, then copy down. We know there's space for at least
  536. // a 10-digit number.
  537. j := len(buf.tmp)
  538. for {
  539. j--
  540. buf.tmp[j] = digits[d%10]
  541. d /= 10
  542. if d == 0 {
  543. break
  544. }
  545. }
  546. return copy(buf.tmp[i:], buf.tmp[j:])
  547. }
  548. func (l *loggingT) println(s severity, args ...interface{}) {
  549. buf := l.header(s)
  550. fmt.Fprintln(buf, args...)
  551. l.output(s, buf)
  552. }
  553. func (l *loggingT) print(s severity, args ...interface{}) {
  554. buf := l.header(s)
  555. fmt.Fprint(buf, args...)
  556. if buf.Bytes()[buf.Len()-1] != '\n' {
  557. buf.WriteByte('\n')
  558. }
  559. l.output(s, buf)
  560. }
  561. func (l *loggingT) printf(s severity, format string, args ...interface{}) {
  562. buf := l.header(s)
  563. fmt.Fprintf(buf, format, args...)
  564. if buf.Bytes()[buf.Len()-1] != '\n' {
  565. buf.WriteByte('\n')
  566. }
  567. l.output(s, buf)
  568. }
  569. // output writes the data to the log files and releases the buffer.
  570. func (l *loggingT) output(s severity, buf *buffer) {
  571. l.mu.Lock()
  572. if l.traceLocation.isSet() {
  573. _, file, line, ok := runtime.Caller(3) // It's always the same number of frames to the user's call (same as header).
  574. if ok && l.traceLocation.match(file, line) {
  575. buf.Write(stacks(false))
  576. }
  577. }
  578. data := buf.Bytes()
  579. if l.toStderr {
  580. os.Stderr.Write(data)
  581. } else {
  582. if l.alsoToStderr || s >= l.stderrThreshold.get() {
  583. os.Stderr.Write(data)
  584. }
  585. if l.file[s] == nil {
  586. if err := l.createFiles(s); err != nil {
  587. os.Stderr.Write(data) // Make sure the message appears somewhere.
  588. l.exit(err)
  589. }
  590. }
  591. switch s {
  592. case fatalLog:
  593. l.file[fatalLog].Write(data)
  594. fallthrough
  595. case errorLog:
  596. l.file[errorLog].Write(data)
  597. fallthrough
  598. case warningLog:
  599. l.file[warningLog].Write(data)
  600. fallthrough
  601. case infoLog:
  602. l.file[infoLog].Write(data)
  603. }
  604. }
  605. if s == fatalLog {
  606. // Make sure we see the trace for the current goroutine on standard error.
  607. if !l.toStderr {
  608. os.Stderr.Write(stacks(false))
  609. }
  610. // Write the stack trace for all goroutines to the files.
  611. trace := stacks(true)
  612. logExitFunc = func(error) {} // If we get a write error, we'll still exit below.
  613. for log := fatalLog; log >= infoLog; log-- {
  614. if f := l.file[log]; f != nil { // Can be nil if -logtostderr is set.
  615. f.Write(trace)
  616. }
  617. }
  618. l.mu.Unlock()
  619. timeoutFlush(10 * time.Second)
  620. os.Exit(255) // C++ uses -1, which is silly because it's anded with 255 anyway.
  621. }
  622. l.putBuffer(buf)
  623. l.mu.Unlock()
  624. if stats := severityStats[s]; stats != nil {
  625. atomic.AddInt64(&stats.lines, 1)
  626. atomic.AddInt64(&stats.bytes, int64(len(data)))
  627. }
  628. }
  629. // timeoutFlush calls Flush and returns when it completes or after timeout
  630. // elapses, whichever happens first. This is needed because the hooks invoked
  631. // by Flush may deadlock when glog.Fatal is called from a hook that holds
  632. // a lock.
  633. func timeoutFlush(timeout time.Duration) {
  634. done := make(chan bool, 1)
  635. go func() {
  636. Flush() // calls logging.lockAndFlushAll()
  637. done <- true
  638. }()
  639. select {
  640. case <-done:
  641. case <-time.After(timeout):
  642. fmt.Fprintln(os.Stderr, "glog: Flush took longer than", timeout)
  643. }
  644. }
  645. // stacks is a wrapper for runtime.Stack that attempts to recover the data for all goroutines.
  646. func stacks(all bool) []byte {
  647. // We don't know how big the traces are, so grow a few times if they don't fit. Start large, though.
  648. n := 10000
  649. if all {
  650. n = 100000
  651. }
  652. var trace []byte
  653. for i := 0; i < 5; i++ {
  654. trace = make([]byte, n)
  655. nbytes := runtime.Stack(trace, all)
  656. if nbytes < len(trace) {
  657. return trace[:nbytes]
  658. }
  659. n *= 2
  660. }
  661. return trace
  662. }
  663. // logExitFunc provides a simple mechanism to override the default behavior
  664. // of exiting on error. Used in testing and to guarantee we reach a required exit
  665. // for fatal logs. Instead, exit could be a function rather than a method but that
  666. // would make its use clumsier.
  667. var logExitFunc func(error)
  668. // exit is called if there is trouble creating or writing log files.
  669. // It flushes the logs and exits the program; there's no point in hanging around.
  670. // l.mu is held.
  671. func (l *loggingT) exit(err error) {
  672. fmt.Fprintf(os.Stderr, "log: exiting because of error: %s\n", err)
  673. // If logExitFunc is set, we do that instead of exiting.
  674. if logExitFunc != nil {
  675. logExitFunc(err)
  676. return
  677. }
  678. l.flushAll()
  679. os.Exit(2)
  680. }
  681. // syncBuffer joins a bufio.Writer to its underlying file, providing access to the
  682. // file's Sync method and providing a wrapper for the Write method that provides log
  683. // file rotation. There are conflicting methods, so the file cannot be embedded.
  684. // l.mu is held for all its methods.
  685. type syncBuffer struct {
  686. logger *loggingT
  687. *bufio.Writer
  688. file *os.File
  689. sev severity
  690. nbytes uint64 // The number of bytes written to this file
  691. }
  692. func (sb *syncBuffer) Sync() error {
  693. return sb.file.Sync()
  694. }
  695. func (sb *syncBuffer) Write(p []byte) (n int, err error) {
  696. if sb.nbytes+uint64(len(p)) >= MaxSize {
  697. if err := sb.rotateFile(time.Now()); err != nil {
  698. sb.logger.exit(err)
  699. }
  700. }
  701. n, err = sb.Writer.Write(p)
  702. sb.nbytes += uint64(n)
  703. if err != nil {
  704. sb.logger.exit(err)
  705. }
  706. return
  707. }
  708. // rotateFile closes the syncBuffer's file and starts a new one.
  709. func (sb *syncBuffer) rotateFile(now time.Time) error {
  710. if sb.file != nil {
  711. sb.Flush()
  712. sb.file.Close()
  713. }
  714. var err error
  715. sb.file, _, err = create(severityName[sb.sev], now)
  716. sb.nbytes = 0
  717. if err != nil {
  718. return err
  719. }
  720. sb.Writer = bufio.NewWriterSize(sb.file, bufferSize)
  721. // Write header.
  722. var buf bytes.Buffer
  723. fmt.Fprintf(&buf, "Log file created at: %s\n", now.Format("2006/01/02 15:04:05"))
  724. fmt.Fprintf(&buf, "Running on machine: %s\n", host)
  725. fmt.Fprintf(&buf, "Binary: Built with %s %s for %s/%s\n", runtime.Compiler, runtime.Version(), runtime.GOOS, runtime.GOARCH)
  726. fmt.Fprintf(&buf, "Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg\n")
  727. n, err := sb.file.Write(buf.Bytes())
  728. sb.nbytes += uint64(n)
  729. return err
  730. }
  731. // bufferSize sizes the buffer associated with each log file. It's large
  732. // so that log records can accumulate without the logging thread blocking
  733. // on disk I/O. The flushDaemon will block instead.
  734. const bufferSize = 256 * 1024
  735. // createFiles creates all the log files for severity from sev down to infoLog.
  736. // l.mu is held.
  737. func (l *loggingT) createFiles(sev severity) error {
  738. now := time.Now()
  739. // Files are created in decreasing severity order, so as soon as we find one
  740. // has already been created, we can stop.
  741. for s := sev; s >= infoLog && l.file[s] == nil; s-- {
  742. sb := &syncBuffer{
  743. logger: l,
  744. sev: s,
  745. }
  746. if err := sb.rotateFile(now); err != nil {
  747. return err
  748. }
  749. l.file[s] = sb
  750. }
  751. return nil
  752. }
  753. const flushInterval = 30 * time.Second
  754. // flushDaemon periodically flushes the log file buffers.
  755. func (l *loggingT) flushDaemon() {
  756. for _ = range time.NewTicker(flushInterval).C {
  757. l.lockAndFlushAll()
  758. }
  759. }
  760. // lockAndFlushAll is like flushAll but locks l.mu first.
  761. func (l *loggingT) lockAndFlushAll() {
  762. l.mu.Lock()
  763. l.flushAll()
  764. l.mu.Unlock()
  765. }
  766. // flushAll flushes all the logs and attempts to "sync" their data to disk.
  767. // l.mu is held.
  768. func (l *loggingT) flushAll() {
  769. // Flush from fatal down, in case there's trouble flushing.
  770. for s := fatalLog; s >= infoLog; s-- {
  771. file := l.file[s]
  772. if file != nil {
  773. file.Flush() // ignore error
  774. file.Sync() // ignore error
  775. }
  776. }
  777. }
  778. // setV computes and remembers the V level for a given PC
  779. // when vmodule is enabled.
  780. // File pattern matching takes the basename of the file, stripped
  781. // of its .go suffix, and uses filepath.Match, which is a little more
  782. // general than the *? matching used in C++.
  783. // l.mu is held.
  784. func (l *loggingT) setV(pc uintptr) Level {
  785. fn := runtime.FuncForPC(pc)
  786. file, _ := fn.FileLine(pc)
  787. // The file is something like /a/b/c/d.go. We want just the d.
  788. if strings.HasSuffix(file, ".go") {
  789. file = file[:len(file)-3]
  790. }
  791. if slash := strings.LastIndex(file, "/"); slash >= 0 {
  792. file = file[slash+1:]
  793. }
  794. for _, filter := range l.vmodule.filter {
  795. if filter.match(file) {
  796. l.vmap[pc] = filter.level
  797. return filter.level
  798. }
  799. }
  800. l.vmap[pc] = 0
  801. return 0
  802. }
  803. // Verbose is a boolean type that implements Infof (like Printf) etc.
  804. // See the documentation of V for more information.
  805. type Verbose bool
  806. // V reports whether verbosity at the call site is at least the requested level.
  807. // The returned value is a boolean of type Verbose, which implements Info, Infoln
  808. // and Infof. These methods will write to the Info log if called.
  809. // Thus, one may write either
  810. // if glog.V(2) { glog.Info("log this") }
  811. // or
  812. // glog.V(2).Info("log this")
  813. // The second form is shorter but the first is cheaper if logging is off because it does
  814. // not evaluate its arguments.
  815. //
  816. // Whether an individual call to V generates a log record depends on the setting of
  817. // the -v and --vmodule flags; both are off by default. If the level in the call to
  818. // V is at least the value of -v, or of -vmodule for the source file containing the
  819. // call, the V call will log.
  820. func V(level Level) Verbose {
  821. // This function tries hard to be cheap unless there's work to do.
  822. // The fast path is two atomic loads and compares.
  823. // Here is a cheap but safe test to see if V logging is enabled globally.
  824. if logging.verbosity.get() >= level {
  825. return Verbose(true)
  826. }
  827. // It's off globally but it vmodule may still be set.
  828. // Here is another cheap but safe test to see if vmodule is enabled.
  829. if atomic.LoadInt32(&logging.filterLength) > 0 {
  830. // Now we need a proper lock to use the logging structure. The pcs field
  831. // is shared so we must lock before accessing it. This is fairly expensive,
  832. // but if V logging is enabled we're slow anyway.
  833. logging.mu.Lock()
  834. defer logging.mu.Unlock()
  835. if runtime.Callers(2, logging.pcs[:]) == 0 {
  836. return Verbose(false)
  837. }
  838. v, ok := logging.vmap[logging.pcs[0]]
  839. if !ok {
  840. v = logging.setV(logging.pcs[0])
  841. }
  842. return Verbose(v >= level)
  843. }
  844. return Verbose(false)
  845. }
  846. // Info is equivalent to the global Info function, guarded by the value of v.
  847. // See the documentation of V for usage.
  848. func (v Verbose) Info(args ...interface{}) {
  849. if v {
  850. logging.print(infoLog, args...)
  851. }
  852. }
  853. // Infoln is equivalent to the global Infoln function, guarded by the value of v.
  854. // See the documentation of V for usage.
  855. func (v Verbose) Infoln(args ...interface{}) {
  856. if v {
  857. logging.println(infoLog, args...)
  858. }
  859. }
  860. // Infof is equivalent to the global Infof function, guarded by the value of v.
  861. // See the documentation of V for usage.
  862. func (v Verbose) Infof(format string, args ...interface{}) {
  863. if v {
  864. logging.printf(infoLog, format, args...)
  865. }
  866. }
  867. // Info logs to the INFO log.
  868. // Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
  869. func Info(args ...interface{}) {
  870. logging.print(infoLog, args...)
  871. }
  872. // Infoln logs to the INFO log.
  873. // Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
  874. func Infoln(args ...interface{}) {
  875. logging.println(infoLog, args...)
  876. }
  877. // Infof logs to the INFO log.
  878. // Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
  879. func Infof(format string, args ...interface{}) {
  880. logging.printf(infoLog, format, args...)
  881. }
  882. // Warning logs to the WARNING and INFO logs.
  883. // Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
  884. func Warning(args ...interface{}) {
  885. logging.print(warningLog, args...)
  886. }
  887. // Warningln logs to the WARNING and INFO logs.
  888. // Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
  889. func Warningln(args ...interface{}) {
  890. logging.println(warningLog, args...)
  891. }
  892. // Warningf logs to the WARNING and INFO logs.
  893. // Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
  894. func Warningf(format string, args ...interface{}) {
  895. logging.printf(warningLog, format, args...)
  896. }
  897. // Error logs to the ERROR, WARNING, and INFO logs.
  898. // Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
  899. func Error(args ...interface{}) {
  900. logging.print(errorLog, args...)
  901. }
  902. // Errorln logs to the ERROR, WARNING, and INFO logs.
  903. // Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
  904. func Errorln(args ...interface{}) {
  905. logging.println(errorLog, args...)
  906. }
  907. // Errorf logs to the ERROR, WARNING, and INFO logs.
  908. // Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
  909. func Errorf(format string, args ...interface{}) {
  910. logging.printf(errorLog, format, args...)
  911. }
  912. // Fatal logs to the FATAL, ERROR, WARNING, and INFO logs,
  913. // including a stack trace of all running goroutines, then calls os.Exit(255).
  914. // Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
  915. func Fatal(args ...interface{}) {
  916. logging.print(fatalLog, args...)
  917. }
  918. // Fatalln logs to the FATAL, ERROR, WARNING, and INFO logs,
  919. // including a stack trace of all running goroutines, then calls os.Exit(255).
  920. // Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
  921. func Fatalln(args ...interface{}) {
  922. logging.println(fatalLog, args...)
  923. }
  924. // Fatalf logs to the FATAL, ERROR, WARNING, and INFO logs,
  925. // including a stack trace of all running goroutines, then calls os.Exit(255).
  926. // Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
  927. func Fatalf(format string, args ...interface{}) {
  928. logging.printf(fatalLog, format, args...)
  929. }