@@ -2,6 +2,7 @@ package main
22
33import (
44 "context"
5+ "encoding/json"
56 "fmt"
67 "io"
78 "os"
@@ -26,6 +27,15 @@ var labels = os.Getenv("LABELS")
2627var typ = os .Getenv ("TYPE" )
2728var debugFile * os.File
2829
30+ var indexFilePath = filepath .Join (pkg .ConfigData .LogsPath , "checkpoint.json" )
31+
32+ type checkpoint struct {
33+ LastResourceVersion string
34+ FileOffsets map [string ]int64 // Filepath -> Offset to last entry in that file.
35+ }
36+
37+ var checkpointData checkpoint
38+
2939func logToDebug (msg string ) {
3040 if _ , err := debugFile .WriteString (fmt .Sprintf ("%s - %s\n " , time .Now ().Format ("2006-01-02 15:04:05" ), msg )); err != nil {
3141 fmt .Println (err )
@@ -45,9 +55,67 @@ func initialiseDebugFile() {
4555 }
4656 }
4757}
58+
59+ func readCheckpoint () {
60+ // Open the file with read/write mode, create it if it doesn't exist
61+ file , err := os .OpenFile (indexFilePath , os .O_RDWR | os .O_CREATE , 0644 )
62+ if err != nil {
63+ panic ("failed to open/create checkpoint file: " + err .Error ())
64+ }
65+ defer file .Close ()
66+
67+ // Read the file content
68+ bytCheckpnt , err := io .ReadAll (file )
69+ if err != nil {
70+ panic ("failed to read checkpoint file: " + err .Error ())
71+ }
72+
73+ // If the file is empty (newly created), initialize default data
74+ if len (bytCheckpnt ) == 0 {
75+ checkpointData = checkpoint {
76+ LastResourceVersion : "" ,
77+ FileOffsets : make (map [string ]int64 ),
78+ }
79+ // Marshal the default data and write it to the file
80+ data , err := json .Marshal (checkpointData )
81+ if err != nil {
82+ panic ("failed to marshal default checkpoint data: " + err .Error ())
83+ }
84+ if _ , err := file .Write (data ); err != nil {
85+ panic ("failed to write default checkpoint data: " + err .Error ())
86+ }
87+ return
88+ }
89+
90+ // Unmarshal existing data
91+ if err := json .Unmarshal (bytCheckpnt , & checkpointData ); err != nil {
92+ panic ("failed to unmarshal checkpoint data: " + err .Error ())
93+ }
94+ }
95+
96+ func writeCheckpoint () {
97+ bytCheckpnt , err := json .Marshal (checkpointData )
98+ if err != nil {
99+ panic ("could not read the checkpoint data at" )
100+ }
101+ file , err := os .OpenFile (indexFilePath , os .O_WRONLY | os .O_TRUNC | os .O_CREATE , 0644 )
102+ if err != nil {
103+ fmt .Println ("Error opening file:" , err )
104+ return
105+ }
106+ _ , err = file .Write (bytCheckpnt )
107+ if err != nil {
108+ fmt .Println ("Error writing to file:" , err )
109+ return
110+ }
111+ file .Close ()
112+ }
113+
48114func main () {
49115 logToDebug ("Starting logger..." )
50116 initialiseDebugFile ()
117+ readCheckpoint ()
118+ defer writeCheckpoint ()
51119 kubeconfig := clientcmd .NewDefaultClientConfigLoadingRules ().GetDefaultFilename ()
52120 config , err := clientcmd .BuildConfigFromFlags ("" , kubeconfig )
53121 if err != nil {
@@ -66,6 +134,9 @@ func main() {
66134 if labels != "" {
67135 opts .LabelSelector = labels
68136 }
137+ if checkpointData .LastResourceVersion != "" {
138+ opts .ResourceVersion = checkpointData .LastResourceVersion
139+ }
69140 initialList , err := cs .CoreV1 ().Pods (namespace ).List (context .TODO (), opts )
70141 if err != nil {
71142 logToDebug ("Exiting runner..." + err .Error ())
@@ -140,6 +211,8 @@ func processPod(ctx context.Context, cs *kubernetes.Clientset, pod *v1.Pod, name
140211 syscall .Flock (int (f .Fd ()), syscall .LOCK_UN )
141212 f .Close ()
142213
214+ //TODO: Can there be a race condition here?
215+ checkpointData .LastResourceVersion = pod .ResourceVersion
143216 //Start watching and recording logs
144217 go func (podName string ) {
145218 logToDebug ("Watching logs for pod: " + podName )
0 commit comments