eventpath.go 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. package pathing
  2. import (
  3. "fmt"
  4. "path"
  5. "time"
  6. )
  7. // 2006-01-02T15:04:05Z07:00
  8. // EventStorageTimeFormat is YYYYMMDDHHmmss
  9. const EventStorageTimeFormat = "20060102150405"
  10. // EventStoragePathFormatter is an implementation of the StoragePathFormatter interface for
  11. // a cluster separated storage path of the format:
  12. //
  13. // <root>/<cluster>/<event>/<sub-paths...>/YYYYMMDDHHmmss
  14. type EventStoragePathFormatter struct {
  15. rootDir string
  16. clusterId string
  17. event string
  18. subPaths []string
  19. }
  20. // NewEventStoragePathFormatter creates a StoragePathFormatter for a cluster separated storage path
  21. // with the given root directory, cluster id, pipeline, and resolution. To omit the resolution directory
  22. // structure, provide a `nil` resolution.
  23. func NewEventStoragePathFormatter(rootDir, clusterId, event string, subPaths ...string) (StoragePathFormatter[time.Time], error) {
  24. if clusterId == "" {
  25. return nil, fmt.Errorf("cluster id cannot be empty")
  26. }
  27. if event == "" {
  28. return nil, fmt.Errorf("event cannot be empty")
  29. }
  30. for _, subPath := range subPaths {
  31. if subPath == "" {
  32. return nil, fmt.Errorf("subpaths cannot be empty")
  33. }
  34. }
  35. return &EventStoragePathFormatter{
  36. rootDir: rootDir,
  37. clusterId: clusterId,
  38. event: event,
  39. subPaths: subPaths,
  40. }, nil
  41. }
  42. // Dir returns the director that files will be placed in
  43. func (espf *EventStoragePathFormatter) Dir() string {
  44. return path.Join(
  45. espf.rootDir,
  46. espf.clusterId,
  47. espf.event,
  48. path.Join(espf.subPaths...),
  49. )
  50. }
  51. // ToFullPath returns the full path to a file name within the storage directory using the format:
  52. //
  53. // <root>/<cluster>/<event>/YYYYMMDDHHmm.json
  54. func (espf *EventStoragePathFormatter) ToFullPath(prefix string, timestamp time.Time, fileExt string) string {
  55. fileName := toEventFileName(prefix, timestamp, fileExt)
  56. return path.Join(
  57. espf.rootDir,
  58. espf.clusterId,
  59. espf.event,
  60. path.Join(espf.subPaths...),
  61. fileName,
  62. )
  63. }
  64. // toEventFileName formats the file name as <prefix>.<timestamp>. if a non-empty fileExt is provided,
  65. // then the file extension is appended to the file name.
  66. func toEventFileName(prefix string, timestamp time.Time, fileExt string) string {
  67. suffix := timestamp.Format(EventStorageTimeFormat)
  68. if fileExt != "" {
  69. suffix = fmt.Sprintf("%s.%s", suffix, fileExt)
  70. }
  71. if prefix == "" {
  72. return suffix
  73. }
  74. return fmt.Sprintf("%s.%s", prefix, suffix)
  75. }