-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
solnicki
committed
Nov 5, 2024
1 parent
487c905
commit 771373e
Showing
11 changed files
with
205 additions
and
773 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package anonymizer | ||
|
||
import ( | ||
"encoding/csv" | ||
"fmt" | ||
"io" | ||
"os" | ||
) | ||
|
||
// AnonymizeCSV takes a CSV file containing logs and transforms it into a list of maps, where each map entry represents a log line. | ||
// Such format is required to be able to modify log data (replace original values with anonymous values). | ||
// It is also returning names of the CSV columns. Names of the columns (field names) are needed to grab corresponding anonymization data. | ||
func AnonymizeCSV(input *os.File, output io.Writer, anonymizer *Anonymizer) error { | ||
csvReader := csv.NewReader(input) | ||
|
||
// First element of the csvReader contains field names | ||
fieldNames, err := csvReader.Read() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
for { | ||
row, err := csvReader.Read() | ||
if err != nil { | ||
break | ||
} | ||
|
||
logLine := make(map[string]string) | ||
for i, val := range row { | ||
logLine[fieldNames[i]] = val | ||
} | ||
|
||
anonymizedLogLine := anonymizer.Anonymize(logLine) | ||
|
||
_, err = io.WriteString(output, anonymizedLogLine) | ||
if err != nil { | ||
return fmt.Errorf("writing anonymized data: %v", err) | ||
} | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package anonymizer | ||
|
||
import ( | ||
"bytes" | ||
"os" | ||
"testing" | ||
|
||
"github.com/logmanager-oss/logveil/internal/parser" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestAnonimizer_CSVloader(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
inputFilename string | ||
outputFilename string | ||
anonDataDir string | ||
expectedOutput string | ||
}{ | ||
{ | ||
name: "Test CSVLoader", | ||
inputFilename: "../../examples/logs/example_logs.csv", | ||
anonDataDir: "../../examples/anon_data", | ||
expectedOutput: "{\"@timestamp\": \"2024-06-05T14:59:27.000+00:00\", \"msg.src_ip\":\"10.20.0.53\", \"username\":\"ladislav.dosek\", \"organization\":\"Apple\"}", | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
input, err := os.Open(tt.inputFilename) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
defer input.Close() | ||
|
||
var output bytes.Buffer | ||
|
||
anonData, err := parser.LoadAnonData(tt.anonDataDir) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
anonymizer := New(anonData) | ||
// Disabling randomization so we know which values to expect | ||
anonymizer.setRandFunc(func(int) int { return 1 }) | ||
|
||
err = AnonymizeCSV(input, &output, anonymizer) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
assert.Equal(t, tt.expectedOutput, output.String()) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,44 +1,58 @@ | ||
package anonymizer | ||
|
||
import ( | ||
"fmt" | ||
"io" | ||
"log/slog" | ||
"os" | ||
|
||
"github.com/logmanager-oss/logveil/internal/flags" | ||
"github.com/logmanager-oss/logveil/internal/parser" | ||
"github.com/logmanager-oss/logveil/internal/writer" | ||
) | ||
|
||
func Run() { | ||
slog.Info("Anonymization process started...") | ||
|
||
anonDataDir, inputFile, outputFile := flags.Load() | ||
anonDataDir, inputFilename, outputFilename, enableLMexport := flags.Load() | ||
|
||
fieldNames, csvData, err := parser.ParseCSV(inputFile) | ||
input, err := os.Open(inputFilename) | ||
if err != nil { | ||
slog.Error("reading input file %s: %v", inputFile, err) | ||
return | ||
} | ||
defer func(fs *os.File) { | ||
if err := fs.Close(); err != nil { | ||
slog.Error(err.Error()) | ||
} | ||
}(input) | ||
|
||
var output io.Writer | ||
if outputFilename != "" { | ||
output, err = os.Create(outputFilename) | ||
if err != nil { | ||
return | ||
} | ||
defer func(fs *os.File) { | ||
if err := fs.Close(); err != nil { | ||
slog.Error(err.Error()) | ||
} | ||
}(output.(*os.File)) | ||
} else { | ||
output = os.Stdout | ||
} | ||
|
||
anonData, err := parser.ParseAnonData(anonDataDir, fieldNames) | ||
anonData, err := parser.LoadAnonData(anonDataDir) | ||
if err != nil { | ||
slog.Error("loading anonymizing data from dir %s: %v", anonDataDir, err) | ||
return | ||
} | ||
anonymizer := New(anonData) | ||
|
||
anonymizer := New(csvData, anonData) | ||
anonymizedData := anonymizer.anonymize() | ||
if outputFile != "" { | ||
outputwriter := &writer.Output{ | ||
Output: anonymizedData, | ||
} | ||
err := outputwriter.Write(outputFile) | ||
if enableLMexport { | ||
err := AnonymizeCSV(input, output, anonymizer) | ||
if err != nil { | ||
slog.Error("writing anonymized data to output file %s: %v", outputFile, err) | ||
slog.Error("reading input file %s: %v", inputFilename, err) | ||
return | ||
} | ||
} else { | ||
fmt.Println(anonymizedData) | ||
} | ||
|
||
slog.Info("All done. Exiting...") | ||
slog.Info("All done. Exiting...") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.