utilities.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. package internal
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "net/http"
  6. "strconv"
  7. "strings"
  8. "time"
  9. )
  10. // JSONString assists in logging JSON: Based on the formatter used to log
  11. // Context contents, the contents could be marshalled as JSON or just printed
  12. // directly.
  13. type JSONString string
  14. // MarshalJSON returns the JSONString unmodified without any escaping.
  15. func (js JSONString) MarshalJSON() ([]byte, error) {
  16. if "" == js {
  17. return []byte("null"), nil
  18. }
  19. return []byte(js), nil
  20. }
  21. func removeFirstSegment(name string) string {
  22. idx := strings.Index(name, "/")
  23. if -1 == idx {
  24. return name
  25. }
  26. return name[idx+1:]
  27. }
  28. func timeToFloatSeconds(t time.Time) float64 {
  29. return float64(t.UnixNano()) / float64(1000*1000*1000)
  30. }
  31. func timeToFloatMilliseconds(t time.Time) float64 {
  32. return float64(t.UnixNano()) / float64(1000*1000)
  33. }
  34. func floatSecondsToDuration(seconds float64) time.Duration {
  35. nanos := seconds * 1000 * 1000 * 1000
  36. return time.Duration(nanos) * time.Nanosecond
  37. }
  38. func absTimeDiff(t1, t2 time.Time) time.Duration {
  39. if t1.After(t2) {
  40. return t1.Sub(t2)
  41. }
  42. return t2.Sub(t1)
  43. }
  44. func compactJSON(js []byte) []byte {
  45. buf := new(bytes.Buffer)
  46. if err := json.Compact(buf, js); err != nil {
  47. return nil
  48. }
  49. return buf.Bytes()
  50. }
  51. // CompactJSONString removes the whitespace from a JSON string.
  52. func CompactJSONString(js string) string {
  53. out := compactJSON([]byte(js))
  54. return string(out)
  55. }
  56. // GetContentLengthFromHeader gets the content length from a HTTP header, or -1
  57. // if no content length is available.
  58. func GetContentLengthFromHeader(h http.Header) int64 {
  59. if cl := h.Get("Content-Length"); cl != "" {
  60. if contentLength, err := strconv.ParseInt(cl, 10, 64); err == nil {
  61. return contentLength
  62. }
  63. }
  64. return -1
  65. }
  66. // StringLengthByteLimit truncates strings using a byte-limit boundary and
  67. // avoids terminating in the middle of a multibyte character.
  68. func StringLengthByteLimit(str string, byteLimit int) string {
  69. if len(str) <= byteLimit {
  70. return str
  71. }
  72. limitIndex := 0
  73. for pos := range str {
  74. if pos > byteLimit {
  75. break
  76. }
  77. limitIndex = pos
  78. }
  79. return str[0:limitIndex]
  80. }
  81. func timeFromUnixMilliseconds(millis uint64) time.Time {
  82. secs := int64(millis) / 1000
  83. msecsRemaining := int64(millis) % 1000
  84. nsecsRemaining := msecsRemaining * (1000 * 1000)
  85. return time.Unix(secs, nsecsRemaining)
  86. }
  87. // TimeToUnixMilliseconds converts a time into a Unix timestamp in millisecond
  88. // units.
  89. func TimeToUnixMilliseconds(tm time.Time) uint64 {
  90. return uint64(tm.UnixNano()) / uint64(1000*1000)
  91. }