Zawsze przychodzi ten moment gdy trzeba rozwiązać buga na produkcji i jedyne co mamy to logi aplikacji. Okazuje się oczywiście, że nie ma wszystkich informacji w tych logach. Nie ma nawet całkiem podstawowych informacji.
Spotkałem się z sytuacją gdzie był robiony request do serwisu, ale nie wiadomo było do którego dokładnie (brak urla w logach). Innym razem pliki były gdzieś przekopiowywane, ale nie było wiadomo gdzie. Dlaczego doszukanie się tych informacji jest takie trudne (choć nie powinno)?
Przykładowo aplikacja wchodzi w skład większych bytów, jest uruchamiana prze inne aplikacje itd. Zdarza się, że w takich systemach nieporządek jest czymś powszechnym. Cykl releasowania jest skomplikowany na tyle, że nie możemy dorzucić kilku logów w problematycznych miejscach i wypuścić update’u.
Moja propozycja, zrób jeden obiekt Settings, który zbiera wszystkie ustawienia, początkowe. Bardzo możliwe, że taki obiekt już jest (Od Krzyśka Seroki: W przypadku ASP.NET Core mamy IConfiguration). Podczas startu aplikacji trzeba te wszystkie ustawienia zebrać (z linii komend, z pliku/ów konfiguracyjnych, z bazy, wygenerowane ścieżki np. na podstawie UserName). To podejście jest dobre samo w sobie bo robimy to raz a serwis, który je udostępnia jest zarejestrowany w kontenerze Dependency Injection jako singleton.
Jeśli takiego obiektu nie mamy to możemy go stworzyć nawet dynamicznie. Możemy nazywać explicite pole lub pozostawić domyślne nazwy:
var settings = new | |
{ | |
inventoryPath, | |
LocalUserName = userName, | |
}; |
Następnie serializujemy ten obiekt do JSONa i zapisujemy w logu. Pełny przykładowy kod:
public class SettingsLogger | |
{ | |
public static void LogSettings( | |
string inventoryPath, | |
AbcServiceSettings abcServiceSettings) | |
{ | |
string userName = UserNameService.GetUserName(); | |
var settings = new | |
{ | |
inventoryPath, | |
userName, | |
abcServiceSettings | |
}; | |
string serializedSettings = JsonConvert.SerializeObject(settings); | |
Logger.Info(serializedSettings); | |
} | |
} | |
public class AbcServiceSettings | |
{ | |
public string Url { get; set; } | |
} |
JSON po serializacji:
{ | |
"inventoryPath":"C:/Temp/Inventory", | |
"LocalUserName":"krzysztof", | |
"abcServiceSettings":{ | |
"Url":"https://ostrapila.pl" | |
} | |
} |
Trzeba jeszcze pamiętać o ukryciu ewentualnych haseł. Najprościej zrobić to nullując odpowiednie pola. Wiem, wiem, wiem, przyjdzie Junior, zapomni i hasła wyciekną… Przecież dzielicie się wiedzą w projekcie i macie Code Review, co nie?
Pingback: dotnetomaniak.pl
Jeśli chodzi o bezpieczeństwo haseł to najlepiej nie trzymać ich w konfiguracji. Wszędzie gdzie się da najlepiej używać Windows Integrated Security, a tam gdzie się nie da to to trzeba szyfrować odpowiednie sekcji w konfiguracji.
@Czarek dokładnie tak, dzięki za uzupełnienie.