From 559ae48a742e334fc339311911e1dd1c6de879cf Mon Sep 17 00:00:00 2001 From: andrewbengordon Date: Thu, 9 Feb 2023 13:37:03 -0700 Subject: [PATCH 01/21] Finished adding seq monitoring --- docker-compose.yml | 12 ++ src/Mars.MissionControl/Game.cs | 1 + src/Mars.Web/Controllers/GameController.cs | 181 ++++++++++++--------- src/Mars.Web/Mars.Web.csproj | 4 + src/Mars.Web/MultiGameHoster.cs | 5 +- src/Mars.Web/Program.cs | 10 ++ 6 files changed, 136 insertions(+), 77 deletions(-) create mode 100644 docker-compose.yml diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..179a166 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,12 @@ +version: "3.0" +services: + seq: + image: datalust/seq:latest + ports: + - "5341:5341" + - "80:80" + - "45341:45341" + volumes: + - /datadrive:/data + environment: + - ACCEPT_EULA=Y \ No newline at end of file diff --git a/src/Mars.MissionControl/Game.cs b/src/Mars.MissionControl/Game.cs index f45bec2..f216dd3 100644 --- a/src/Mars.MissionControl/Game.cs +++ b/src/Mars.MissionControl/Game.cs @@ -247,6 +247,7 @@ public MoveResult MovePerseverance(PlayerToken token, Direction direction) if (player.PerseveranceLocation == TargetLocation)//you win! { + players.Remove(player.Token, out _); player = player with { WinningTime = DateTime.Now - GameStartedOn }; winners.Enqueue(player); diff --git a/src/Mars.Web/Controllers/GameController.cs b/src/Mars.Web/Controllers/GameController.cs index d662748..0244e92 100644 --- a/src/Mars.Web/Controllers/GameController.cs +++ b/src/Mars.Web/Controllers/GameController.cs @@ -1,4 +1,8 @@ -namespace Mars.Web.Controllers; +using Mars.MissionControl; +using Mars.Web.Pages; +using Microsoft.AspNetCore.Mvc; + +namespace Mars.Web.Controllers; [ApiController] [Route("[controller]")] @@ -6,11 +10,13 @@ public class GameController : ControllerBase { ConcurrentDictionary games; private readonly ConcurrentDictionary tokenMap; + private readonly ILogger logger; - public GameController(MultiGameHoster multiGameHoster) + public GameController(MultiGameHoster multiGameHoster, ILogger logger) { this.games = multiGameHoster.Games; this.tokenMap = multiGameHoster.TokenMap; + this.logger = logger; } /// @@ -24,34 +30,43 @@ public GameController(MultiGameHoster multiGameHoster) [ProducesResponseType(StatusCodes.Status400BadRequest)] public ActionResult Join(string gameId, string name) { - if (games.TryGetValue(gameId, out GameManager? gameManager)) + using (logger.BeginScope($"GameName: {name}, GameId: {gameId}")) { - try + if (games.TryGetValue(gameId, out GameManager? gameManager)) { - var joinResult = gameManager.Game.Join(name); - tokenMap.TryAdd(joinResult.Token.Value, gameId); + try + { + var joinResult = gameManager.Game.Join(name); + tokenMap.TryAdd(joinResult.Token.Value, gameId); + using (logger.BeginScope($"UserToken: {joinResult.Token.Value}")) + { + logger.LogInformation($"New User {joinResult.Token.Value} Joined"); + } - return new JoinResponse + return new JoinResponse + { + Token = joinResult.Token.Value, + StartingColumn = joinResult.PlayerLocation.Column, + StartingRow = joinResult.PlayerLocation.Row, + Neighbors = joinResult.Neighbors.ToDto(), + LowResolutionMap = joinResult.LowResolutionMap.ToDto(), + TargetRow = joinResult.TargetLocation.Row, + TargetColumn = joinResult.TargetLocation.Column, + Orientation = joinResult.Orientation.ToString() + }; + } + catch (TooManyPlayersException) { - Token = joinResult.Token.Value, - StartingColumn = joinResult.PlayerLocation.Column, - StartingRow = joinResult.PlayerLocation.Row, - Neighbors = joinResult.Neighbors.ToDto(), - LowResolutionMap = joinResult.LowResolutionMap.ToDto(), - TargetRow = joinResult.TargetLocation.Row, - TargetColumn = joinResult.TargetLocation.Column, - Orientation = joinResult.Orientation.ToString() - }; + logger.LogError($"Too Many Players"); + return Problem("Cannot join game, too many players.", statusCode: 400, title: "Too many players"); + } } - catch (TooManyPlayersException) + else { - return Problem("Cannot join game, too many players.", statusCode: 400, title: "Too many players"); + logger.LogError("Bad Game ID"); + return Problem("Unrecognized game id.", statusCode: 400, title: "Bad Game ID"); } } - else - { - return Problem("Unrecognized game id.", statusCode: 400, title: "Bad Game ID"); - } } [HttpGet("[action]")] @@ -68,7 +83,7 @@ public ActionResult Status(string token) } } } - + logger.LogError("Unrecognized token"); return Problem("Unrecognized token", statusCode: 400, title: "Bad Token"); } @@ -82,42 +97,49 @@ public ActionResult Status(string token) [ProducesResponseType(StatusCodes.Status400BadRequest)] public ActionResult MovePerseverance(string token, Direction direction) { - if (tokenMap.TryGetValue(token, out string? gameId)) + using (logger.BeginScope($"UserToken: {token}")) { - if (games.TryGetValue(gameId, out var gameManager)) + if (tokenMap.TryGetValue(token, out string? gameId)) { - PlayerToken? playerToken; - if (!gameManager.Game.TryTranslateToken(token, out playerToken)) + if (games.TryGetValue(gameId, out var gameManager)) { - return Problem("Unrecognized token", statusCode: 400, title: "Bad Token"); - } + PlayerToken? playerToken; + if (!gameManager.Game.TryTranslateToken(token, out playerToken)) + { + logger.LogError("Unrecognized token"); + return Problem("Unrecognized token", statusCode: 400, title: "Bad Token"); + } - if (gameManager.Game.GameState != GameState.Playing) - { - return Problem("Unable to move, invalid game state.", statusCode: 400, title: "Game not in the Playing state."); - } + if (gameManager.Game.GameState != GameState.Playing) + { + logger.LogWarning("Unable to move Perserverance, invalid game state."); + return Problem("Unable to move, invalid game state.", statusCode: 400, title: "Game not in the Playing state."); + } - try - { - var moveResult = gameManager.Game.MovePerseverance(playerToken!, direction); - return new MoveResponse + try { - Row = moveResult.Location.Row, - Column = moveResult.Location.Column, - BatteryLevel = moveResult.BatteryLevel, - Neighbors = moveResult.Neighbors.ToDto(), - Message = moveResult.Message, - Orientation = moveResult.Orientation.ToString() - }; - } - catch (Exception ex) - { - return Problem("Unable to move", statusCode: 400, title: ex.Message); + var moveResult = gameManager.Game.MovePerseverance(playerToken!, direction); + logger.LogInformation($"User {token} moved Perseverance {direction}. Move Result: {moveResult.Message}"); + return new MoveResponse + { + Row = moveResult.Location.Row, + Column = moveResult.Location.Column, + BatteryLevel = moveResult.BatteryLevel, + Neighbors = moveResult.Neighbors.ToDto(), + Message = moveResult.Message, + Orientation = moveResult.Orientation.ToString() + }; + } + catch (Exception ex) + { + logger.LogWarning("Unable to move Perserverance"); + return Problem("Unable to move", statusCode: 400, title: ex.Message); + } } } + logger.LogError("Unrecognized token on move request"); + return Problem("Unrecognized token", statusCode: 400, title: "Bad Token"); } - - return Problem("Unrecognized token", statusCode: 400, title: "Bad Token"); } /// @@ -131,40 +153,47 @@ public ActionResult MovePerseverance(string token, Direction direc [ProducesResponseType(StatusCodes.Status400BadRequest)] public ActionResult MoveIngenuity(string token, int destinationRow, int destinationColumn) { - if (tokenMap.TryGetValue(token, out string? gameId)) + using (logger.BeginScope($"UserToken: {token}")) { - if (games.TryGetValue(gameId, out var gameManager)) + if (tokenMap.TryGetValue(token, out string? gameId)) { - PlayerToken? playerToken; - if (!gameManager.Game.TryTranslateToken(token, out playerToken)) + if (games.TryGetValue(gameId, out var gameManager)) { - return Problem("Unrecognized token", statusCode: 400, title: "Bad Token"); - } + PlayerToken? playerToken; + if (!gameManager.Game.TryTranslateToken(token, out playerToken)) + { + logger.LogError("Unrecognized token on move request"); + return Problem("Unrecognized token", statusCode: 400, title: "Bad Token"); + } - if (gameManager.Game.GameState != GameState.Playing) - { - return Problem("Unable to move, invalid game state.", statusCode: 400, title: "Game not in the Playing state."); - } + if (gameManager.Game.GameState != GameState.Playing) + { + logger.LogWarning("Unable to move Ingenuity"); + return Problem("Unable to move, invalid game state.", statusCode: 400, title: "Game not in the Playing state."); + } - try - { - var moveResult = gameManager.Game.MoveIngenuity(playerToken!, new Location(destinationRow, destinationColumn)); - return new IngenuityMoveResponse + try { - Row = moveResult.Location.Row, - Column = moveResult.Location.Column, - Neighbors = moveResult.Neighbors.ToDto(), - Message = moveResult.Message, - BatteryLevel = moveResult.BatteryLevel - }; - } - catch (Exception ex) - { - return Problem("Unable to move", statusCode: 400, title: ex.Message); + var moveResult = gameManager.Game.MoveIngenuity(playerToken!, new Location(destinationRow, destinationColumn)); + logger.LogInformation($"User {token} moved Ingenuity"); + return new IngenuityMoveResponse + { + Row = moveResult.Location.Row, + Column = moveResult.Location.Column, + Neighbors = moveResult.Neighbors.ToDto(), + Message = moveResult.Message, + BatteryLevel = moveResult.BatteryLevel + }; + } + catch (Exception ex) + { + logger.LogWarning("Unable to move Ingenuity"); + return Problem("Unable to move", statusCode: 400, title: ex.Message); + } } } + logger.LogError("Unrecognized token on move request"); + return Problem("Unrecognized token", statusCode: 400, title: "Bad Token"); } - - return Problem("Unrecognized token", statusCode: 400, title: "Bad Token"); } } diff --git a/src/Mars.Web/Mars.Web.csproj b/src/Mars.Web/Mars.Web.csproj index 8910179..385f8dd 100644 --- a/src/Mars.Web/Mars.Web.csproj +++ b/src/Mars.Web/Mars.Web.csproj @@ -17,6 +17,10 @@ + + + + diff --git a/src/Mars.Web/MultiGameHoster.cs b/src/Mars.Web/MultiGameHoster.cs index 55653db..5e041fd 100644 --- a/src/Mars.Web/MultiGameHoster.cs +++ b/src/Mars.Web/MultiGameHoster.cs @@ -4,9 +4,10 @@ public class MultiGameHoster { - public MultiGameHoster(IMapProvider mapProvider) + public MultiGameHoster(IMapProvider mapProvider, ILogger logger) { ParsedMaps = new List(mapProvider.LoadMaps()); + this.logger = logger; } public void RaiseOldGamesPurged() => OldGamesPurged?.Invoke(this, EventArgs.Empty); @@ -18,6 +19,7 @@ public MultiGameHoster(IMapProvider mapProvider) private string nextGame = "a"; private object lockObject = new(); private readonly IWebHostEnvironment hostEnvironment; + private readonly ILogger logger; public string MakeNewGame() { @@ -27,6 +29,7 @@ public string MakeNewGame() Games.TryAdd(gameId, new GameManager(ParsedMaps)); nextGame = IncrementGameId(nextGame); + logger.LogInformation($"New Game Created: {gameId}"); return gameId; } } diff --git a/src/Mars.Web/Program.cs b/src/Mars.Web/Program.cs index 8c16589..bc5ea4e 100644 --- a/src/Mars.Web/Program.cs +++ b/src/Mars.Web/Program.cs @@ -1,10 +1,20 @@ using Mars.Web; using Microsoft.OpenApi.Models; +using Serilog; +using Serilog.Exceptions; using System.Reflection; using System.Text.Json.Serialization; using System.Threading.RateLimiting; var builder = WebApplication.CreateBuilder(args); + +builder.Host.UseSerilog((c, l) => +{ + l.WriteTo.Console() + .Enrich.WithExceptionDetails() + .WriteTo.Seq("http://localhost:80"); +}); + builder.Services.AddApplicationInsightsTelemetry(); builder.Services.AddRazorPages(); builder.Services.AddServerSideBlazor(); From 21f621db1904b2a9ab33969d2337f6def8f0f40b Mon Sep 17 00:00:00 2001 From: Bridger Thompson Date: Mon, 13 Feb 2023 10:45:29 -0700 Subject: [PATCH 02/21] api logging --- src/Mars.Web/Controllers/GameController.cs | 63 ++++++++++++++-------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/src/Mars.Web/Controllers/GameController.cs b/src/Mars.Web/Controllers/GameController.cs index d662748..892e6a5 100644 --- a/src/Mars.Web/Controllers/GameController.cs +++ b/src/Mars.Web/Controllers/GameController.cs @@ -6,12 +6,14 @@ public class GameController : ControllerBase { ConcurrentDictionary games; private readonly ConcurrentDictionary tokenMap; + private readonly ILogger logger; - public GameController(MultiGameHoster multiGameHoster) + public GameController(MultiGameHoster multiGameHoster, ILogger logger) { this.games = multiGameHoster.Games; this.tokenMap = multiGameHoster.TokenMap; - } + this.logger = logger; + } /// /// Join an existing game. You can join in the 'Joining' state, or in the 'Playing' state. @@ -30,8 +32,9 @@ public ActionResult Join(string gameId, string name) { var joinResult = gameManager.Game.Join(name); tokenMap.TryAdd(joinResult.Token.Value, gameId); + logger.LogInformation($"Player {name} joined game {gameId}"); - return new JoinResponse + return new JoinResponse { Token = joinResult.Token.Value, StartingColumn = joinResult.PlayerLocation.Column, @@ -44,13 +47,15 @@ public ActionResult Join(string gameId, string name) }; } catch (TooManyPlayersException) - { - return Problem("Cannot join game, too many players.", statusCode: 400, title: "Too many players"); + { + logger.LogError($"Player {name} failed to join game {gameId}. Too many players"); + return Problem("Cannot join game, too many players.", statusCode: 400, title: "Too many players"); } } else - { - return Problem("Unrecognized game id.", statusCode: 400, title: "Bad Game ID"); + { + logger.LogError($"Player {name} failed to join game {gameId}. Game id not found"); + return Problem("Unrecognized game id.", statusCode: 400, title: "Bad Game ID"); } } @@ -69,7 +74,7 @@ public ActionResult Status(string token) } } - return Problem("Unrecognized token", statusCode: 400, title: "Bad Token"); + return BadToken(token); } /// @@ -89,13 +94,13 @@ public ActionResult MovePerseverance(string token, Direction direc PlayerToken? playerToken; if (!gameManager.Game.TryTranslateToken(token, out playerToken)) { - return Problem("Unrecognized token", statusCode: 400, title: "Bad Token"); + return BadToken(token); } if (gameManager.Game.GameState != GameState.Playing) { - return Problem("Unable to move, invalid game state.", statusCode: 400, title: "Game not in the Playing state."); - } + return CantMove(ex.Message); + } try { @@ -112,13 +117,13 @@ public ActionResult MovePerseverance(string token, Direction direc } catch (Exception ex) { - return Problem("Unable to move", statusCode: 400, title: ex.Message); - } + return CantMove(ex.Message); + } } } - return Problem("Unrecognized token", statusCode: 400, title: "Bad Token"); - } + return BadToken(token); + } /// /// Move the Ingenuity helicopter. @@ -138,13 +143,13 @@ public ActionResult MoveIngenuity(string token, int desti PlayerToken? playerToken; if (!gameManager.Game.TryTranslateToken(token, out playerToken)) { - return Problem("Unrecognized token", statusCode: 400, title: "Bad Token"); - } + return BadToken(token); + } if (gameManager.Game.GameState != GameState.Playing) { - return Problem("Unable to move, invalid game state.", statusCode: 400, title: "Game not in the Playing state."); - } + return CantMove("Game not in the Playing state"); + } try { @@ -160,11 +165,23 @@ public ActionResult MoveIngenuity(string token, int desti } catch (Exception ex) { - return Problem("Unable to move", statusCode: 400, title: ex.Message); - } + return CantMove(ex.Message); + } } } - return Problem("Unrecognized token", statusCode: 400, title: "Bad Token"); - } + return BadToken(token); + } + + public ObjectResult BadToken(string token) + { + logger.LogError($"Unrecogized token {token}"); + return Problem("Unrecognized token", statusCode: 400, title: "Bad Token"); + } + + public ObjectResult CantMove(string message) + { + logger.LogError($"Could not move: {message}"); + return Problem("Unable to move", statusCode: 400, title: message); + } } From 64c5b9e21a0803871f97bdc3b5e71f70ed22abee Mon Sep 17 00:00:00 2001 From: garv5014 Date: Mon, 13 Feb 2023 10:49:05 -0700 Subject: [PATCH 03/21] porblem details --- src/Mars.Web/Mars.Web.csproj | 1 + src/Mars.Web/Program.cs | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/src/Mars.Web/Mars.Web.csproj b/src/Mars.Web/Mars.Web.csproj index 8910179..915de6a 100644 --- a/src/Mars.Web/Mars.Web.csproj +++ b/src/Mars.Web/Mars.Web.csproj @@ -15,6 +15,7 @@ + diff --git a/src/Mars.Web/Program.cs b/src/Mars.Web/Program.cs index 8c16589..f8e0421 100644 --- a/src/Mars.Web/Program.cs +++ b/src/Mars.Web/Program.cs @@ -3,6 +3,7 @@ using System.Reflection; using System.Text.Json.Serialization; using System.Threading.RateLimiting; +using Hellang.Middleware.ProblemDetails; var builder = WebApplication.CreateBuilder(args); builder.Services.AddApplicationInsightsTelemetry(); @@ -13,6 +14,13 @@ options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); }); builder.Services.AddEndpointsApiExplorer(); + +builder.Services.AddProblemDetails(opts => +{ + opts.IncludeExceptionDetails = (ctx, ex) => false; +} +); + builder.Services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "Mars Rover", Version = "v1" }); From cdaa8eb2e573b08d1422c1d4e38220e53ea1a1f7 Mon Sep 17 00:00:00 2001 From: garv5014 Date: Mon, 13 Feb 2023 12:38:23 -0700 Subject: [PATCH 04/21] added scopes to a few areas --- src/Mars.Web/Controllers/GameController.cs | 167 +++++++++++---------- src/Mars.Web/Mars.Web.csproj | 5 +- src/Mars.Web/Program.cs | 11 ++ src/Mars.Web/appsettings.json | 35 +++-- 4 files changed, 125 insertions(+), 93 deletions(-) diff --git a/src/Mars.Web/Controllers/GameController.cs b/src/Mars.Web/Controllers/GameController.cs index 892e6a5..5f35bf7 100644 --- a/src/Mars.Web/Controllers/GameController.cs +++ b/src/Mars.Web/Controllers/GameController.cs @@ -6,14 +6,14 @@ public class GameController : ControllerBase { ConcurrentDictionary games; private readonly ConcurrentDictionary tokenMap; - private readonly ILogger logger; + private readonly ILogger logger; - public GameController(MultiGameHoster multiGameHoster, ILogger logger) + public GameController(MultiGameHoster multiGameHoster, ILogger logger) { this.games = multiGameHoster.Games; this.tokenMap = multiGameHoster.TokenMap; - this.logger = logger; - } + this.logger = logger; + } /// /// Join an existing game. You can join in the 'Joining' state, or in the 'Playing' state. @@ -30,11 +30,14 @@ public ActionResult Join(string gameId, string name) { try { + var joinResult = gameManager.Game.Join(name); tokenMap.TryAdd(joinResult.Token.Value, gameId); - logger.LogInformation($"Player {name} joined game {gameId}"); - - return new JoinResponse + using (logger.BeginScope("User: {ScopeUser} GameId: {ScopeGameId} ", joinResult.Token.Value, gameId)) + { + logger.LogInformation($"Player {name} joined game {gameId}"); + } + return new JoinResponse { Token = joinResult.Token.Value, StartingColumn = joinResult.PlayerLocation.Column, @@ -47,15 +50,15 @@ public ActionResult Join(string gameId, string name) }; } catch (TooManyPlayersException) - { - logger.LogError($"Player {name} failed to join game {gameId}. Too many players"); - return Problem("Cannot join game, too many players.", statusCode: 400, title: "Too many players"); + { + logger.LogError($"Player {name} failed to join game {gameId}. Too many players"); + return Problem("Cannot join game, too many players.", statusCode: 400, title: "Too many players"); } } else - { - logger.LogError($"Player {name} failed to join game {gameId}. Game id not found"); - return Problem("Unrecognized game id.", statusCode: 400, title: "Bad Game ID"); + { + logger.LogError($"Player {name} failed to join game {gameId}. Game id not found"); + return Problem("Unrecognized game id.", statusCode: 400, title: "Bad Game ID"); } } @@ -73,8 +76,11 @@ public ActionResult Status(string token) } } } - - return BadToken(token); + using (logger.BeginScope("User: {ScopeUser} GameId: {ScopeGameId} ", token, gameId)) + { + logger.LogError($"Unrecogized token {token}"); + return Problem("Unrecognized token", statusCode: 400, title: "Bad Token"); + } } /// @@ -89,41 +95,48 @@ public ActionResult MovePerseverance(string token, Direction direc { if (tokenMap.TryGetValue(token, out string? gameId)) { - if (games.TryGetValue(gameId, out var gameManager)) + using (logger.BeginScope("User: {ScopeUser} GameId: {ScopeGameId} ", token, gameId)) { - PlayerToken? playerToken; - if (!gameManager.Game.TryTranslateToken(token, out playerToken)) + if (games.TryGetValue(gameId, out var gameManager)) { - return BadToken(token); - } + PlayerToken? playerToken; + if (!gameManager.Game.TryTranslateToken(token, out playerToken)) + { + logger.LogError($"Unrecogized token {token}"); + return Problem("Unrecognized token", statusCode: 400, title: "Bad Token"); + } - if (gameManager.Game.GameState != GameState.Playing) - { - return CantMove(ex.Message); - } + if (gameManager.Game.GameState != GameState.Playing) + { + logger.LogError($"Could not move: Game not in Playing state."); + return Problem("Unable to move", statusCode: 400, title: "Game not in Playing state."); + } - try - { - var moveResult = gameManager.Game.MovePerseverance(playerToken!, direction); - return new MoveResponse + try { - Row = moveResult.Location.Row, - Column = moveResult.Location.Column, - BatteryLevel = moveResult.BatteryLevel, - Neighbors = moveResult.Neighbors.ToDto(), - Message = moveResult.Message, - Orientation = moveResult.Orientation.ToString() - }; + var moveResult = gameManager.Game.MovePerseverance(playerToken!, direction); + return new MoveResponse + { + Row = moveResult.Location.Row, + Column = moveResult.Location.Column, + BatteryLevel = moveResult.BatteryLevel, + Neighbors = moveResult.Neighbors.ToDto(), + Message = moveResult.Message, + Orientation = moveResult.Orientation.ToString() + }; + } + catch (Exception ex) + { + logger.LogError($"Could not move: {ex.Message}"); + return Problem("Unable to move", statusCode: 400, title: ex.Message); + } } - catch (Exception ex) - { - return CantMove(ex.Message); - } + } } - - return BadToken(token); - } + logger.LogError($"Unrecogized token {token}"); + return Problem("Unrecognized token", statusCode: 400, title: "Bad Token"); + } /// /// Move the Ingenuity helicopter. @@ -138,50 +151,44 @@ public ActionResult MoveIngenuity(string token, int desti { if (tokenMap.TryGetValue(token, out string? gameId)) { - if (games.TryGetValue(gameId, out var gameManager)) + using (logger.BeginScope("User: {ScopeUser} GameId: {ScopeGameId} ", token, gameId)) { - PlayerToken? playerToken; - if (!gameManager.Game.TryTranslateToken(token, out playerToken)) + if (games.TryGetValue(gameId, out var gameManager)) { - return BadToken(token); - } + PlayerToken? playerToken; + if (!gameManager.Game.TryTranslateToken(token, out playerToken)) + { + logger.LogError($"Unrecogized token {token}"); + return Problem("Unrecognized token", statusCode: 400, title: "Bad Token"); + } - if (gameManager.Game.GameState != GameState.Playing) - { - return CantMove("Game not in the Playing state"); - } + if (gameManager.Game.GameState != GameState.Playing) + { + logger.LogError($"Could not move: Game not in Playing state."); + return Problem("Unable to move", statusCode: 400, title: "Game not in Playing state."); + } - try - { - var moveResult = gameManager.Game.MoveIngenuity(playerToken!, new Location(destinationRow, destinationColumn)); - return new IngenuityMoveResponse + try { - Row = moveResult.Location.Row, - Column = moveResult.Location.Column, - Neighbors = moveResult.Neighbors.ToDto(), - Message = moveResult.Message, - BatteryLevel = moveResult.BatteryLevel - }; + var moveResult = gameManager.Game.MoveIngenuity(playerToken!, new Location(destinationRow, destinationColumn)); + return new IngenuityMoveResponse + { + Row = moveResult.Location.Row, + Column = moveResult.Location.Column, + Neighbors = moveResult.Neighbors.ToDto(), + Message = moveResult.Message, + BatteryLevel = moveResult.BatteryLevel + }; + } + catch (Exception ex) + { + logger.LogError($"Could not move: {ex.Message}"); + return Problem("Unable to move", statusCode: 400, title: ex.Message); + } } - catch (Exception ex) - { - return CantMove(ex.Message); - } } } - - return BadToken(token); - } - - public ObjectResult BadToken(string token) - { - logger.LogError($"Unrecogized token {token}"); - return Problem("Unrecognized token", statusCode: 400, title: "Bad Token"); - } - - public ObjectResult CantMove(string message) - { - logger.LogError($"Could not move: {message}"); - return Problem("Unable to move", statusCode: 400, title: message); - } + logger.LogError($"Unrecogized token {token}"); + return Problem("Unrecognized token", statusCode: 400, title: "Bad Token"); + } } diff --git a/src/Mars.Web/Mars.Web.csproj b/src/Mars.Web/Mars.Web.csproj index 915de6a..407f955 100644 --- a/src/Mars.Web/Mars.Web.csproj +++ b/src/Mars.Web/Mars.Web.csproj @@ -16,8 +16,11 @@ - + + + + diff --git a/src/Mars.Web/Program.cs b/src/Mars.Web/Program.cs index f8e0421..1298c7a 100644 --- a/src/Mars.Web/Program.cs +++ b/src/Mars.Web/Program.cs @@ -4,6 +4,8 @@ using System.Text.Json.Serialization; using System.Threading.RateLimiting; using Hellang.Middleware.ProblemDetails; +using Serilog; +using Serilog.Exceptions; var builder = WebApplication.CreateBuilder(args); builder.Services.AddApplicationInsightsTelemetry(); @@ -15,6 +17,15 @@ }); builder.Services.AddEndpointsApiExplorer(); +builder.Host.UseSerilog( (context, loggerConfig) => + { + loggerConfig.WriteTo.Console() + .Enrich.WithExceptionDetails() + .WriteTo.Seq("http://localhost:5340"); + } + + ); + builder.Services.AddProblemDetails(opts => { opts.IncludeExceptionDetails = (ctx, ex) => false; diff --git a/src/Mars.Web/appsettings.json b/src/Mars.Web/appsettings.json index 735cde4..1b3be71 100644 --- a/src/Mars.Web/appsettings.json +++ b/src/Mars.Web/appsettings.json @@ -1,12 +1,23 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - }, - "AllowedHosts": "*", - "GAME_PASSWORD": "password", - "CleanupFrequencyMinutes": "60", - "ApiLimitPerSecond": "10" -} +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + }, + "Console": { + "FormatterName": "json", + "FormatterOptions": { + "SingleLine": true, + "IncludeScopes": true, + "UseUtcTimestamp": true, + "TimestampFormat": "HH:mm:ss", + "JsonWriterOptions": { "Indented": true + } + } + } + }, + "AllowedHosts": "*", + "GAME_PASSWORD": "password", + "CleanupFrequencyMinutes": "60", + "ApiLimitPerSecond": "10" +} From 1c98353aa9e19b6f3af39e235e14cbf7e96bbda3 Mon Sep 17 00:00:00 2001 From: "Breanna.nesbit" Date: Mon, 13 Feb 2023 17:35:23 -0700 Subject: [PATCH 05/21] Breanna's and Aubrey's logs --- src/Mars.MissionControl/Game.cs | 17 +++++++++++++++-- src/Mars.MissionControl/Helpers.cs | 10 ++++++++-- .../Mars.MissionControl.csproj | 4 ++++ src/Mars.Web/GameManager.cs | 12 +++++++++--- src/Mars.Web/Mars.Web.csproj | 3 +++ src/Mars.Web/MultiGameHoster.cs | 7 +++++-- src/Mars.Web/Program.cs | 15 +++++++++++++++ 7 files changed, 59 insertions(+), 9 deletions(-) diff --git a/src/Mars.MissionControl/Game.cs b/src/Mars.MissionControl/Game.cs index 7cc7abe..e426295 100644 --- a/src/Mars.MissionControl/Game.cs +++ b/src/Mars.MissionControl/Game.cs @@ -1,9 +1,10 @@ -using System.Collections.ObjectModel; +using Microsoft.Extensions.Logging; +using System.Collections.ObjectModel; namespace Mars.MissionControl; public class Game : IDisposable { - public Game(GameStartOptions startOptions) + public Game(GameStartOptions startOptions, ILogger logger) { GameState = GameState.Joining; Board = new Board(startOptions.Map); @@ -13,8 +14,12 @@ public Game(GameStartOptions startOptions) IngenuityVisibilityRadius = startOptions.IngenuityVisibilityRadius; StartingBatteryLevel = startOptions.StartingBatteryLevel; IngenuityStartingBatteryLevel = Board.Width * 2 + Board.Height * 2; + this.logger= logger; + } + + public int MapNumber => Board.MapNumber; public Location TargetLocation { get; private set; } @@ -49,11 +54,13 @@ public JoinResult Join(string playerName) { if (GameState != GameState.Joining && GameState != GameState.Playing) { + logger.LogError("Game wasn't detected"); throw new InvalidGameStateException(); } var player = new Player(playerName); var startingLocation = Board.PlaceNewPlayer(player); + logger.LogInformation("New player came into existance and started at location ({x}, {y}) ", startingLocation.X, startingLocation.Y); player = player with { BatteryLevel = StartingBatteryLevel, @@ -65,6 +72,7 @@ public JoinResult Join(string playerName) if (!players.TryAdd(player.Token, player) || !playerTokenCache.TryAdd(player.Token.Value, player.Token)) { + logger.LogError($"Player {player.Token.Value} couldn't be added"); throw new Exception("Unable to add new player...that token already exists?!"); } @@ -90,6 +98,8 @@ private static Orientation getRandomOrientation() public GameState GameState { get; set; } public Board Board { get; private set; } private Timer? rechargeTimer; + private readonly ILogger logger; + public DateTime GameStartedOn { get; private set; } public void PlayGame() => PlayGame(new GamePlayOptions()); @@ -169,6 +179,7 @@ public IngenuityMoveResult MoveIngenuity(PlayerToken token, Location destination } raiseStateChange(); + logger.LogInformation("player: {name} moved helicopter correctly and moved to location: {loc}", player.Name, player.IngenuityLocation); return new IngenuityMoveResult( player.IngenuityLocation, @@ -176,6 +187,7 @@ public IngenuityMoveResult MoveIngenuity(PlayerToken token, Location destination Board.GetNeighbors(player.IngenuityLocation, IngenuityVisibilityRadius), message ?? throw new Exception("Game message not set?!") ); + } public MoveResult MovePerseverance(PlayerToken token, Direction direction) @@ -253,6 +265,7 @@ public MoveResult MovePerseverance(PlayerToken token, Direction direction) } raiseStateChange(); + logger.LogInformation("player: {0} moved rover correctly", player.Name); return new MoveResult( player.PerseveranceLocation, diff --git a/src/Mars.MissionControl/Helpers.cs b/src/Mars.MissionControl/Helpers.cs index 98c1072..7c4dc8d 100644 --- a/src/Mars.MissionControl/Helpers.cs +++ b/src/Mars.MissionControl/Helpers.cs @@ -1,9 +1,14 @@ -namespace Mars.MissionControl; +using Microsoft.Extensions.Logging; +using System.Runtime.CompilerServices; + +namespace Mars.MissionControl; public static class Helpers { + private static ILogger logger; public static Map CreateMap(int height, int width) { + var cells = new List(); for (int x = 0; x < width; x++) { @@ -30,11 +35,12 @@ public static Game CreateGame(int height, int width) public static Game CreateGame(Map map) { + var startOptions = new GameStartOptions { Map = map }; - var game = new Game(startOptions); + var game = new Game(startOptions, logger); return game; } diff --git a/src/Mars.MissionControl/Mars.MissionControl.csproj b/src/Mars.MissionControl/Mars.MissionControl.csproj index a1ed5b3..f4b2e01 100644 --- a/src/Mars.MissionControl/Mars.MissionControl.csproj +++ b/src/Mars.MissionControl/Mars.MissionControl.csproj @@ -6,4 +6,8 @@ enable + + + + diff --git a/src/Mars.Web/GameManager.cs b/src/Mars.Web/GameManager.cs index 6c13148..f49fb00 100644 --- a/src/Mars.Web/GameManager.cs +++ b/src/Mars.Web/GameManager.cs @@ -4,7 +4,9 @@ namespace Mars.Web; public class GameManager { - public GameManager(List maps) + private readonly ILogger logger; + + public GameManager(List maps, ILogger logger) { CreatedOn = DateTime.Now; GameStartOptions = new GameStartOptions @@ -12,7 +14,7 @@ public GameManager(List maps) Map = maps[0], }; this.Maps = maps; - + this.logger = logger; StartNewGame(GameStartOptions); } public IReadOnlyList Maps { get; } @@ -50,12 +52,16 @@ public void StartNewGame(GameStartOptions startOptions) if (Game != null) { Game.GameStateChanged -= Game_GameStateChanged; + var playoptions = Game.GamePlayOptions; Game.Dispose(); + logger.LogWarning("Game ending {0}", playoptions); + } NewGameStarted?.Invoke(this, new EventArgs()); - Game = new Game(startOptions); + Game = new Game(startOptions, logger); + logger.LogInformation("New game created"); GameStateChanged?.Invoke(this, EventArgs.Empty); //subscribe to new event diff --git a/src/Mars.Web/Mars.Web.csproj b/src/Mars.Web/Mars.Web.csproj index 8910179..fc67c6f 100644 --- a/src/Mars.Web/Mars.Web.csproj +++ b/src/Mars.Web/Mars.Web.csproj @@ -17,6 +17,9 @@ + + + diff --git a/src/Mars.Web/MultiGameHoster.cs b/src/Mars.Web/MultiGameHoster.cs index 4a124e8..f4c226c 100644 --- a/src/Mars.Web/MultiGameHoster.cs +++ b/src/Mars.Web/MultiGameHoster.cs @@ -4,9 +4,10 @@ public class MultiGameHoster { - public MultiGameHoster(IMapProvider mapProvider) + public MultiGameHoster(IMapProvider mapProvider, ILogger log) { ParsedMaps = new List(mapProvider.LoadMaps()); + this.log = log; } public void RaiseOldGamesPurged() => OldGamesPurged?.Invoke(this, EventArgs.Empty); @@ -18,13 +19,15 @@ public MultiGameHoster(IMapProvider mapProvider) private string nextGame = "a"; private object lockObject = new(); private readonly IWebHostEnvironment hostEnvironment; + private readonly ILogger log; public string MakeNewGame() { + lock (lockObject) { var gameId = nextGame; - Games.TryAdd(gameId, new GameManager(ParsedMaps)); + Games.TryAdd(gameId, new GameManager(ParsedMaps, log)); nextGame = IncrementGameId(nextGame); return gameId; diff --git a/src/Mars.Web/Program.cs b/src/Mars.Web/Program.cs index 8c16589..bddeb67 100644 --- a/src/Mars.Web/Program.cs +++ b/src/Mars.Web/Program.cs @@ -1,9 +1,13 @@ using Mars.Web; using Microsoft.OpenApi.Models; +using Serilog; +using Serilog.Exceptions; using System.Reflection; +using System.Runtime.InteropServices; using System.Text.Json.Serialization; using System.Threading.RateLimiting; + var builder = WebApplication.CreateBuilder(args); builder.Services.AddApplicationInsightsTelemetry(); builder.Services.AddRazorPages(); @@ -20,6 +24,17 @@ c.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename)); }); + +builder.Host.UseSerilog((context, loggerConfig) => +{ + loggerConfig.WriteTo.Console() + .Enrich.WithExceptionDetails() + .WriteTo.Seq("http://localhost:5341"); +}); + + + + builder.Services.AddSingleton(); builder.Services.AddSingleton(); From 3a2d5158083e0da4cebf82b7a4cee9d1830ceabb Mon Sep 17 00:00:00 2001 From: Jonathan Allen Date: Tue, 14 Feb 2023 10:32:23 -0700 Subject: [PATCH 06/21] add docker support --- src/.dockerignore | 25 +++++++++++++++ src/Mars.Web/Dockerfile | 24 ++++++++++++++ src/Mars.Web/Mars.Web.csproj | 2 ++ src/Mars.Web/Properties/launchSettings.json | 35 +++++++++++++-------- 4 files changed, 73 insertions(+), 13 deletions(-) create mode 100644 src/.dockerignore create mode 100644 src/Mars.Web/Dockerfile diff --git a/src/.dockerignore b/src/.dockerignore new file mode 100644 index 0000000..3729ff0 --- /dev/null +++ b/src/.dockerignore @@ -0,0 +1,25 @@ +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/azds.yaml +**/bin +**/charts +**/docker-compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md \ No newline at end of file diff --git a/src/Mars.Web/Dockerfile b/src/Mars.Web/Dockerfile new file mode 100644 index 0000000..04e40d9 --- /dev/null +++ b/src/Mars.Web/Dockerfile @@ -0,0 +1,24 @@ +#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging. + +FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base +WORKDIR /app +EXPOSE 80 +EXPOSE 443 + +FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build +WORKDIR /src +COPY ["Mars.Web/Mars.Web.csproj", "Mars.Web/"] +COPY ["Mars.MissionControl/Mars.MissionControl.csproj", "Mars.MissionControl/"] +COPY ["Mars.Web.Types/Mars.Web.Types.csproj", "Mars.Web.Types/"] +RUN dotnet restore "Mars.Web/Mars.Web.csproj" +COPY . . +WORKDIR "/src/Mars.Web" +RUN dotnet build "Mars.Web.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "Mars.Web.csproj" -c Release -o /app/publish /p:UseAppHost=false + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "Mars.Web.dll"] \ No newline at end of file diff --git a/src/Mars.Web/Mars.Web.csproj b/src/Mars.Web/Mars.Web.csproj index 8910179..2931021 100644 --- a/src/Mars.Web/Mars.Web.csproj +++ b/src/Mars.Web/Mars.Web.csproj @@ -6,6 +6,7 @@ enable 1c3d0055-a8d7-4fc1-a151-6dbc7e1b1d38 True + Linux @@ -17,6 +18,7 @@ + diff --git a/src/Mars.Web/Properties/launchSettings.json b/src/Mars.Web/Properties/launchSettings.json index 29d99f9..9f091b1 100644 --- a/src/Mars.Web/Properties/launchSettings.json +++ b/src/Mars.Web/Properties/launchSettings.json @@ -1,28 +1,22 @@ { - "iisSettings": { - "iisExpress": { - "applicationUrl": "http://localhost:26097", - "sslPort": 44335 - } - }, "profiles": { "http": { "commandName": "Project", - "dotnetRunMessages": true, "launchBrowser": true, - "applicationUrl": "http://localhost:5110", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" - } + }, + "dotnetRunMessages": true, + "applicationUrl": "http://localhost:5110" }, "https": { "commandName": "Project", - "dotnetRunMessages": true, "launchBrowser": true, - "applicationUrl": "https://localhost:7287;http://localhost:5110", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" - } + }, + "dotnetRunMessages": true, + "applicationUrl": "https://localhost:7287;http://localhost:5110" }, "IIS Express": { "commandName": "IISExpress", @@ -30,6 +24,21 @@ "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } + }, + "Docker": { + "commandName": "Docker", + "launchBrowser": true, + "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}", + "publishAllPorts": true, + "useSSL": true + } + }, + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:26097", + "sslPort": 44335 } } -} +} \ No newline at end of file From ffe9f2cb6b9a06f962ce1fa48273185de2521f43 Mon Sep 17 00:00:00 2001 From: Jonathan Allen Date: Tue, 14 Feb 2023 10:38:48 -0700 Subject: [PATCH 07/21] add docker compose --- src/Mars.Web/Mars.Web.csproj | 1 + src/MarsRover.sln | 6 ++++++ src/docker-compose.dcproj | 18 ++++++++++++++++++ src/docker-compose.override.yml | 13 +++++++++++++ src/docker-compose.yml | 19 +++++++++++++++++++ 5 files changed, 57 insertions(+) create mode 100644 src/docker-compose.dcproj create mode 100644 src/docker-compose.override.yml create mode 100644 src/docker-compose.yml diff --git a/src/Mars.Web/Mars.Web.csproj b/src/Mars.Web/Mars.Web.csproj index 2931021..89f4619 100644 --- a/src/Mars.Web/Mars.Web.csproj +++ b/src/Mars.Web/Mars.Web.csproj @@ -7,6 +7,7 @@ 1c3d0055-a8d7-4fc1-a151-6dbc7e1b1d38 True Linux + ..\docker-compose.dcproj diff --git a/src/MarsRover.sln b/src/MarsRover.sln index b76f6cf..950cd82 100644 --- a/src/MarsRover.sln +++ b/src/MarsRover.sln @@ -13,6 +13,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mars.Web.Tests", "Mars.Web. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mars.Web.Types", "Mars.Web.Types\Mars.Web.Types.csproj", "{A92385B4-ADF1-4201-970E-915A57426B5D}" EndProject +Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{A037F803-1212-4594-AA2D-3967B97CC735}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -39,6 +41,10 @@ Global {A92385B4-ADF1-4201-970E-915A57426B5D}.Debug|Any CPU.Build.0 = Debug|Any CPU {A92385B4-ADF1-4201-970E-915A57426B5D}.Release|Any CPU.ActiveCfg = Release|Any CPU {A92385B4-ADF1-4201-970E-915A57426B5D}.Release|Any CPU.Build.0 = Release|Any CPU + {A037F803-1212-4594-AA2D-3967B97CC735}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A037F803-1212-4594-AA2D-3967B97CC735}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A037F803-1212-4594-AA2D-3967B97CC735}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A037F803-1212-4594-AA2D-3967B97CC735}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/docker-compose.dcproj b/src/docker-compose.dcproj new file mode 100644 index 0000000..478a8fa --- /dev/null +++ b/src/docker-compose.dcproj @@ -0,0 +1,18 @@ + + + + 2.1 + Linux + a037f803-1212-4594-aa2d-3967b97cc735 + LaunchBrowser + {Scheme}://localhost:{ServicePort} + mars.web + + + + docker-compose.yml + + + + + \ No newline at end of file diff --git a/src/docker-compose.override.yml b/src/docker-compose.override.yml new file mode 100644 index 0000000..e5856f2 --- /dev/null +++ b/src/docker-compose.override.yml @@ -0,0 +1,13 @@ +version: '3.4' + +services: + mars.web: + environment: + - ASPNETCORE_ENVIRONMENT=Development + - ASPNETCORE_URLS=https://+:443;http://+:80 + ports: + - "80" + - "443" + volumes: + - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro + - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro \ No newline at end of file diff --git a/src/docker-compose.yml b/src/docker-compose.yml new file mode 100644 index 0000000..a91955b --- /dev/null +++ b/src/docker-compose.yml @@ -0,0 +1,19 @@ +version: '3.4' + +services: + mars.web: + image: ${DOCKER_REGISTRY-}marsweb + build: + context: . + dockerfile: Mars.Web/Dockerfile + + seq: + image: datalust/seq:latest + ports: + - "5341:5341" + - "80:80" + - "45341:45341" + volumes: + - /datadrive:/data + environment: + - ACCEPT_EULA=Y \ No newline at end of file From 7552cc364cddd5d983c2103706006745cc877fbf Mon Sep 17 00:00:00 2001 From: Jonathan Allen Date: Tue, 14 Feb 2023 10:42:19 -0700 Subject: [PATCH 08/21] add container name, change ports --- src/docker-compose.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/docker-compose.yml b/src/docker-compose.yml index a91955b..24fd943 100644 --- a/src/docker-compose.yml +++ b/src/docker-compose.yml @@ -8,10 +8,12 @@ services: dockerfile: Mars.Web/Dockerfile seq: + container_name: seq image: datalust/seq:latest ports: - - "5341:5341" - - "80:80" + # Host Port : Container Port + - "8888:5341" + - "8085:80" - "45341:45341" volumes: - /datadrive:/data From fefaf0d560f444c7d12610ef6327b27462e755f8 Mon Sep 17 00:00:00 2001 From: andrewbengordon Date: Tue, 14 Feb 2023 12:09:42 -0700 Subject: [PATCH 09/21] Fixed API controller, added docker support --- src/.dockerignore | 25 ++++ src/Mars.Web/Controllers/GameController.cs | 144 +++++++++----------- src/Mars.Web/Dockerfile | 24 ++++ src/Mars.Web/Mars.Web.csproj | 3 + src/Mars.Web/Program.cs | 2 +- src/Mars.Web/Properties/launchSettings.json | 35 +++-- src/MarsRover.sln | 6 + src/docker-compose.dcproj | 18 +++ src/docker-compose.override.yml | 13 ++ src/docker-compose.yml | 17 +++ 10 files changed, 197 insertions(+), 90 deletions(-) create mode 100644 src/.dockerignore create mode 100644 src/Mars.Web/Dockerfile create mode 100644 src/docker-compose.dcproj create mode 100644 src/docker-compose.override.yml create mode 100644 src/docker-compose.yml diff --git a/src/.dockerignore b/src/.dockerignore new file mode 100644 index 0000000..3729ff0 --- /dev/null +++ b/src/.dockerignore @@ -0,0 +1,25 @@ +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/azds.yaml +**/bin +**/charts +**/docker-compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md \ No newline at end of file diff --git a/src/Mars.Web/Controllers/GameController.cs b/src/Mars.Web/Controllers/GameController.cs index 1f2b5da..cbcda13 100644 --- a/src/Mars.Web/Controllers/GameController.cs +++ b/src/Mars.Web/Controllers/GameController.cs @@ -46,12 +46,12 @@ public ActionResult Join(string gameId, string name) return new JoinResponse { Token = joinResult.Token.Value, - StartingColumn = joinResult.PlayerLocation.Column, - StartingRow = joinResult.PlayerLocation.Row, + StartingX = joinResult.PlayerLocation.X, + StartingY = joinResult.PlayerLocation.Y, Neighbors = joinResult.Neighbors.ToDto(), LowResolutionMap = joinResult.LowResolutionMap.ToDto(), - TargetRow = joinResult.TargetLocation.Row, - TargetColumn = joinResult.TargetLocation.Column, + TargetX = joinResult.TargetLocation.X, + TargetY = joinResult.TargetLocation.Y, Orientation = joinResult.Orientation.ToString() }; } @@ -74,20 +74,18 @@ public ActionResult Join(string gameId, string name) [ProducesResponseType(StatusCodes.Status400BadRequest)] public ActionResult Status(string token) { - if (tokenMap.TryGetValue(token, out string? gameId) && + using (logger.BeginScope($"UserToken: {token}")) + { + if (tokenMap.TryGetValue(token, out string? gameId) && games.TryGetValue(gameId, out var gameManager) && gameManager.Game.TryTranslateToken(token, out _)) - { - if (games.TryGetValue(gameId, out var gameManager)) { - if (gameManager.Game.TryTranslateToken(token, out _)) - { - return new StatusResponse { Status = gameManager.Game.GameState.ToString() }; - } + logger.LogInformation("Getting game status"); + return new StatusResponse { Status = gameManager.Game.GameState.ToString() }; } + logger.LogError("Unrecognized token"); + return Problem("Unrecognized token", statusCode: 400, title: "Bad Token"); } - logger.LogError("Unrecognized token"); - return Problem("Unrecognized token", statusCode: 400, title: "Bad Token"); } /// @@ -99,49 +97,46 @@ public ActionResult Status(string token) [HttpGet("[action]")] [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(PerseveranceMoveResponse))] [ProducesResponseType(StatusCodes.Status400BadRequest)] - public ActionResult MovePerseverance(string token, Direction direction) + public ActionResult MovePerseverance(string token, Direction direction) { using (logger.BeginScope($"UserToken: {token}")) { - if (tokenMap.TryGetValue(token, out string? gameId)) + if (tokenMap.TryGetValue(token, out string? gameId) && games.TryGetValue(gameId, out var gameManager)) { - if (games.TryGetValue(gameId, out var gameManager)) + PlayerToken? playerToken; + if (!gameManager.Game.TryTranslateToken(token, out playerToken)) { - PlayerToken? playerToken; - if (!gameManager.Game.TryTranslateToken(token, out playerToken)) - { - logger.LogError("Unrecognized token"); - return Problem("Unrecognized token", statusCode: 400, title: "Bad Token"); - } + logger.LogError("Unrecognized token"); + return Problem("Unrecognized token", statusCode: 400, title: "Bad Token"); + } - if (gameManager.Game.GameState != GameState.Playing) - { - logger.LogWarning("Unable to move Perserverance, invalid game state."); - return Problem("Unable to move, invalid game state.", statusCode: 400, title: "Game not in the Playing state."); - } + if (gameManager.Game.GameState != GameState.Playing) + { + logger.LogWarning("Unable to move Perserverance, invalid game state."); + return Problem("Unable to move, invalid game state.", statusCode: 400, title: "Game not in the Playing state."); + } - try - { - var moveResult = gameManager.Game.MovePerseverance(playerToken!, direction); - logger.LogInformation($"User {token} moved Perseverance {direction}. Move Result: {moveResult.Message}"); - return new MoveResponse - { - Row = moveResult.Location.Row, - Column = moveResult.Location.Column, - BatteryLevel = moveResult.BatteryLevel, - Neighbors = moveResult.Neighbors.ToDto(), - Message = moveResult.Message, - Orientation = moveResult.Orientation.ToString() - }; - } - catch (Exception ex) + try + { + var moveResult = gameManager.Game.MovePerseverance(playerToken!, direction); + logger.LogInformation($"User {token} moved Perseverance {direction}. Move Result: {moveResult.Message}"); + return new PerseveranceMoveResponse { - logger.LogWarning("Unable to move Perserverance"); - return Problem("Unable to move", statusCode: 400, title: ex.Message); - } + X = moveResult.Location.X, + Y = moveResult.Location.Y, + BatteryLevel = moveResult.BatteryLevel, + Neighbors = moveResult.Neighbors.ToDto(), + Message = moveResult.Message, + Orientation = moveResult.Orientation.ToString() + }; + } + catch (Exception ex) + { + logger.LogWarning("Unable to move Perserverance"); + return Problem("Unable to move", statusCode: 400, title: ex.Message); } } - logger.LogError("Unrecognized token on move request"); + logger.LogError("Unrecognized token"); return Problem("Unrecognized token", statusCode: 400, title: "Bad Token"); } } @@ -160,41 +155,38 @@ public ActionResult MoveIngenuity(string token, int desti { using (logger.BeginScope($"UserToken: {token}")) { - if (tokenMap.TryGetValue(token, out string? gameId)) + if (tokenMap.TryGetValue(token, out string? gameId) && games.TryGetValue(gameId, out var gameManager)) { - if (games.TryGetValue(gameId, out var gameManager)) + PlayerToken? playerToken; + if (!gameManager.Game.TryTranslateToken(token, out playerToken)) { - PlayerToken? playerToken; - if (!gameManager.Game.TryTranslateToken(token, out playerToken)) - { - logger.LogError("Unrecognized token on move request"); - return Problem("Unrecognized token", statusCode: 400, title: "Bad Token"); - } + logger.LogError("Unrecognized token on move request"); + return Problem("Unrecognized token", statusCode: 400, title: "Bad Token"); + } - if (gameManager.Game.GameState != GameState.Playing) - { - logger.LogWarning("Unable to move Ingenuity"); - return Problem("Unable to move, invalid game state.", statusCode: 400, title: "Game not in the Playing state."); - } + if (gameManager.Game.GameState != GameState.Playing) + { + logger.LogWarning("Unable to move Ingenuity, invalid game state"); + return Problem("Unable to move, invalid game state.", statusCode: 400, title: "Game not in the Playing state."); + } - try - { - var moveResult = gameManager.Game.MoveIngenuity(playerToken!, new Location(destinationRow, destinationColumn)); - logger.LogInformation($"User {token} moved Ingenuity"); - return new IngenuityMoveResponse - { - Row = moveResult.Location.Row, - Column = moveResult.Location.Column, - Neighbors = moveResult.Neighbors.ToDto(), - Message = moveResult.Message, - BatteryLevel = moveResult.BatteryLevel - }; - } - catch (Exception ex) + try + { + var moveResult = gameManager.Game.MoveIngenuity(playerToken!, new Location(destinationRow, destinationColumn)); + logger.LogInformation($"User {token} moved Ingenuity"); + return new IngenuityMoveResponse { - logger.LogWarning("Unable to move Ingenuity"); - return Problem("Unable to move", statusCode: 400, title: ex.Message); - } + X = moveResult.Location.X, + Y = moveResult.Location.Y, + Neighbors = moveResult.Neighbors.ToDto(), + Message = moveResult.Message, + BatteryLevel = moveResult.BatteryLevel + }; + } + catch (Exception ex) + { + logger.LogWarning("Unable to move Ingenuity"); + return Problem("Unable to move", statusCode: 400, title: ex.Message); } } logger.LogError("Unrecognized token on move request"); diff --git a/src/Mars.Web/Dockerfile b/src/Mars.Web/Dockerfile new file mode 100644 index 0000000..04e40d9 --- /dev/null +++ b/src/Mars.Web/Dockerfile @@ -0,0 +1,24 @@ +#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging. + +FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base +WORKDIR /app +EXPOSE 80 +EXPOSE 443 + +FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build +WORKDIR /src +COPY ["Mars.Web/Mars.Web.csproj", "Mars.Web/"] +COPY ["Mars.MissionControl/Mars.MissionControl.csproj", "Mars.MissionControl/"] +COPY ["Mars.Web.Types/Mars.Web.Types.csproj", "Mars.Web.Types/"] +RUN dotnet restore "Mars.Web/Mars.Web.csproj" +COPY . . +WORKDIR "/src/Mars.Web" +RUN dotnet build "Mars.Web.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "Mars.Web.csproj" -c Release -o /app/publish /p:UseAppHost=false + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "Mars.Web.dll"] \ No newline at end of file diff --git a/src/Mars.Web/Mars.Web.csproj b/src/Mars.Web/Mars.Web.csproj index 385f8dd..98afa6f 100644 --- a/src/Mars.Web/Mars.Web.csproj +++ b/src/Mars.Web/Mars.Web.csproj @@ -6,6 +6,8 @@ enable 1c3d0055-a8d7-4fc1-a151-6dbc7e1b1d38 True + Linux + ..\docker-compose.dcproj @@ -17,6 +19,7 @@ + diff --git a/src/Mars.Web/Program.cs b/src/Mars.Web/Program.cs index bc5ea4e..14502a8 100644 --- a/src/Mars.Web/Program.cs +++ b/src/Mars.Web/Program.cs @@ -12,7 +12,7 @@ { l.WriteTo.Console() .Enrich.WithExceptionDetails() - .WriteTo.Seq("http://localhost:80"); + .WriteTo.Seq("http://seq"); }); builder.Services.AddApplicationInsightsTelemetry(); diff --git a/src/Mars.Web/Properties/launchSettings.json b/src/Mars.Web/Properties/launchSettings.json index 29d99f9..9f091b1 100644 --- a/src/Mars.Web/Properties/launchSettings.json +++ b/src/Mars.Web/Properties/launchSettings.json @@ -1,28 +1,22 @@ { - "iisSettings": { - "iisExpress": { - "applicationUrl": "http://localhost:26097", - "sslPort": 44335 - } - }, "profiles": { "http": { "commandName": "Project", - "dotnetRunMessages": true, "launchBrowser": true, - "applicationUrl": "http://localhost:5110", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" - } + }, + "dotnetRunMessages": true, + "applicationUrl": "http://localhost:5110" }, "https": { "commandName": "Project", - "dotnetRunMessages": true, "launchBrowser": true, - "applicationUrl": "https://localhost:7287;http://localhost:5110", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" - } + }, + "dotnetRunMessages": true, + "applicationUrl": "https://localhost:7287;http://localhost:5110" }, "IIS Express": { "commandName": "IISExpress", @@ -30,6 +24,21 @@ "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } + }, + "Docker": { + "commandName": "Docker", + "launchBrowser": true, + "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}", + "publishAllPorts": true, + "useSSL": true + } + }, + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:26097", + "sslPort": 44335 } } -} +} \ No newline at end of file diff --git a/src/MarsRover.sln b/src/MarsRover.sln index b76f6cf..5327fbe 100644 --- a/src/MarsRover.sln +++ b/src/MarsRover.sln @@ -13,6 +13,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mars.Web.Tests", "Mars.Web. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mars.Web.Types", "Mars.Web.Types\Mars.Web.Types.csproj", "{A92385B4-ADF1-4201-970E-915A57426B5D}" EndProject +Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{21739252-74F5-4694-879C-C832B3BD68FF}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -39,6 +41,10 @@ Global {A92385B4-ADF1-4201-970E-915A57426B5D}.Debug|Any CPU.Build.0 = Debug|Any CPU {A92385B4-ADF1-4201-970E-915A57426B5D}.Release|Any CPU.ActiveCfg = Release|Any CPU {A92385B4-ADF1-4201-970E-915A57426B5D}.Release|Any CPU.Build.0 = Release|Any CPU + {21739252-74F5-4694-879C-C832B3BD68FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {21739252-74F5-4694-879C-C832B3BD68FF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {21739252-74F5-4694-879C-C832B3BD68FF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {21739252-74F5-4694-879C-C832B3BD68FF}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/docker-compose.dcproj b/src/docker-compose.dcproj new file mode 100644 index 0000000..24775e1 --- /dev/null +++ b/src/docker-compose.dcproj @@ -0,0 +1,18 @@ + + + + 2.1 + Linux + 21739252-74f5-4694-879c-c832b3bd68ff + LaunchBrowser + {Scheme}://localhost:{ServicePort} + mars.web + + + + docker-compose.yml + + + + + \ No newline at end of file diff --git a/src/docker-compose.override.yml b/src/docker-compose.override.yml new file mode 100644 index 0000000..e5856f2 --- /dev/null +++ b/src/docker-compose.override.yml @@ -0,0 +1,13 @@ +version: '3.4' + +services: + mars.web: + environment: + - ASPNETCORE_ENVIRONMENT=Development + - ASPNETCORE_URLS=https://+:443;http://+:80 + ports: + - "80" + - "443" + volumes: + - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro + - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro \ No newline at end of file diff --git a/src/docker-compose.yml b/src/docker-compose.yml new file mode 100644 index 0000000..064c5dc --- /dev/null +++ b/src/docker-compose.yml @@ -0,0 +1,17 @@ +version: '3.4' + +services: + mars.web: + image: ${DOCKER_REGISTRY-}marsweb + build: + context: . + dockerfile: Mars.Web/Dockerfile + + seq: + image: datalust/seq:latest + ports: + - "8888:80" + volumes: + - /datadrive:/data + environment: + - ACCEPT_EULA=Y \ No newline at end of file From bef5245c53384766256e568da6482c45296e9676 Mon Sep 17 00:00:00 2001 From: garv5014 Date: Wed, 15 Feb 2023 11:37:46 -0700 Subject: [PATCH 10/21] added docker support --- src/.dockerignore | 25 +++++++++++ src/Mars.Web/Dockerfile | 24 +++++++++++ src/Mars.Web/Mars.Web.csproj | 3 ++ src/Mars.Web/Program.cs | 16 +++---- src/Mars.Web/Properties/launchSettings.json | 35 +++++++++------ src/Mars.Web/appsettings.json | 47 +++++++++++---------- src/MarsRover.sln | 6 +++ src/docker-compose.dcproj | 18 ++++++++ src/docker-compose.override.yml | 13 ++++++ src/docker-compose.yml | 18 ++++++++ 10 files changed, 160 insertions(+), 45 deletions(-) create mode 100644 src/.dockerignore create mode 100644 src/Mars.Web/Dockerfile create mode 100644 src/docker-compose.dcproj create mode 100644 src/docker-compose.override.yml create mode 100644 src/docker-compose.yml diff --git a/src/.dockerignore b/src/.dockerignore new file mode 100644 index 0000000..3729ff0 --- /dev/null +++ b/src/.dockerignore @@ -0,0 +1,25 @@ +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/azds.yaml +**/bin +**/charts +**/docker-compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md \ No newline at end of file diff --git a/src/Mars.Web/Dockerfile b/src/Mars.Web/Dockerfile new file mode 100644 index 0000000..04e40d9 --- /dev/null +++ b/src/Mars.Web/Dockerfile @@ -0,0 +1,24 @@ +#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging. + +FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base +WORKDIR /app +EXPOSE 80 +EXPOSE 443 + +FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build +WORKDIR /src +COPY ["Mars.Web/Mars.Web.csproj", "Mars.Web/"] +COPY ["Mars.MissionControl/Mars.MissionControl.csproj", "Mars.MissionControl/"] +COPY ["Mars.Web.Types/Mars.Web.Types.csproj", "Mars.Web.Types/"] +RUN dotnet restore "Mars.Web/Mars.Web.csproj" +COPY . . +WORKDIR "/src/Mars.Web" +RUN dotnet build "Mars.Web.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "Mars.Web.csproj" -c Release -o /app/publish /p:UseAppHost=false + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "Mars.Web.dll"] \ No newline at end of file diff --git a/src/Mars.Web/Mars.Web.csproj b/src/Mars.Web/Mars.Web.csproj index 407f955..e20e01d 100644 --- a/src/Mars.Web/Mars.Web.csproj +++ b/src/Mars.Web/Mars.Web.csproj @@ -6,6 +6,8 @@ enable 1c3d0055-a8d7-4fc1-a151-6dbc7e1b1d38 True + Linux + ..\docker-compose.dcproj @@ -18,6 +20,7 @@ + diff --git a/src/Mars.Web/Program.cs b/src/Mars.Web/Program.cs index 1298c7a..d3fa617 100644 --- a/src/Mars.Web/Program.cs +++ b/src/Mars.Web/Program.cs @@ -17,16 +17,14 @@ }); builder.Services.AddEndpointsApiExplorer(); -builder.Host.UseSerilog( (context, loggerConfig) => - { - loggerConfig.WriteTo.Console() - .Enrich.WithExceptionDetails() - .WriteTo.Seq("http://localhost:5340"); - } - - ); +builder.Host.UseSerilog((context, loggerConfig) => +{ + loggerConfig.WriteTo.Console() + .Enrich.WithExceptionDetails() + .WriteTo.Seq("http://seq"); +}); -builder.Services.AddProblemDetails(opts => +builder.Services.AddProblemDetails(opts => { opts.IncludeExceptionDetails = (ctx, ex) => false; } diff --git a/src/Mars.Web/Properties/launchSettings.json b/src/Mars.Web/Properties/launchSettings.json index 29d99f9..9f091b1 100644 --- a/src/Mars.Web/Properties/launchSettings.json +++ b/src/Mars.Web/Properties/launchSettings.json @@ -1,28 +1,22 @@ { - "iisSettings": { - "iisExpress": { - "applicationUrl": "http://localhost:26097", - "sslPort": 44335 - } - }, "profiles": { "http": { "commandName": "Project", - "dotnetRunMessages": true, "launchBrowser": true, - "applicationUrl": "http://localhost:5110", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" - } + }, + "dotnetRunMessages": true, + "applicationUrl": "http://localhost:5110" }, "https": { "commandName": "Project", - "dotnetRunMessages": true, "launchBrowser": true, - "applicationUrl": "https://localhost:7287;http://localhost:5110", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" - } + }, + "dotnetRunMessages": true, + "applicationUrl": "https://localhost:7287;http://localhost:5110" }, "IIS Express": { "commandName": "IISExpress", @@ -30,6 +24,21 @@ "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } + }, + "Docker": { + "commandName": "Docker", + "launchBrowser": true, + "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}", + "publishAllPorts": true, + "useSSL": true + } + }, + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:26097", + "sslPort": 44335 } } -} +} \ No newline at end of file diff --git a/src/Mars.Web/appsettings.json b/src/Mars.Web/appsettings.json index 1b3be71..5db8342 100644 --- a/src/Mars.Web/appsettings.json +++ b/src/Mars.Web/appsettings.json @@ -1,23 +1,24 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - }, - "Console": { - "FormatterName": "json", - "FormatterOptions": { - "SingleLine": true, - "IncludeScopes": true, - "UseUtcTimestamp": true, - "TimestampFormat": "HH:mm:ss", - "JsonWriterOptions": { "Indented": true - } - } - } - }, - "AllowedHosts": "*", - "GAME_PASSWORD": "password", - "CleanupFrequencyMinutes": "60", - "ApiLimitPerSecond": "10" -} +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + }, + "Console": { + "FormatterName": "json", + "FormatterOptions": { + "SingleLine": true, + "IncludeScopes": true, + "UseUtcTimestamp": true, + "TimestampFormat": "HH:mm:ss", + "JsonWriterOptions": { + "Indented": true + } + } + } + }, + "AllowedHosts": "*", + "GAME_PASSWORD": "password", + "CleanupFrequencyMinutes": "60", + "ApiLimitPerSecond": "10" +} diff --git a/src/MarsRover.sln b/src/MarsRover.sln index b76f6cf..31dcdbb 100644 --- a/src/MarsRover.sln +++ b/src/MarsRover.sln @@ -13,6 +13,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mars.Web.Tests", "Mars.Web. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mars.Web.Types", "Mars.Web.Types\Mars.Web.Types.csproj", "{A92385B4-ADF1-4201-970E-915A57426B5D}" EndProject +Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{196B3946-5D88-42B2-9DD7-48217B960394}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -39,6 +41,10 @@ Global {A92385B4-ADF1-4201-970E-915A57426B5D}.Debug|Any CPU.Build.0 = Debug|Any CPU {A92385B4-ADF1-4201-970E-915A57426B5D}.Release|Any CPU.ActiveCfg = Release|Any CPU {A92385B4-ADF1-4201-970E-915A57426B5D}.Release|Any CPU.Build.0 = Release|Any CPU + {196B3946-5D88-42B2-9DD7-48217B960394}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {196B3946-5D88-42B2-9DD7-48217B960394}.Debug|Any CPU.Build.0 = Debug|Any CPU + {196B3946-5D88-42B2-9DD7-48217B960394}.Release|Any CPU.ActiveCfg = Release|Any CPU + {196B3946-5D88-42B2-9DD7-48217B960394}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/docker-compose.dcproj b/src/docker-compose.dcproj new file mode 100644 index 0000000..90b5a34 --- /dev/null +++ b/src/docker-compose.dcproj @@ -0,0 +1,18 @@ + + + + 2.1 + Linux + 196b3946-5d88-42b2-9dd7-48217b960394 + LaunchBrowser + {Scheme}://localhost:{ServicePort} + mars.web + + + + docker-compose.yml + + + + + \ No newline at end of file diff --git a/src/docker-compose.override.yml b/src/docker-compose.override.yml new file mode 100644 index 0000000..e5856f2 --- /dev/null +++ b/src/docker-compose.override.yml @@ -0,0 +1,13 @@ +version: '3.4' + +services: + mars.web: + environment: + - ASPNETCORE_ENVIRONMENT=Development + - ASPNETCORE_URLS=https://+:443;http://+:80 + ports: + - "80" + - "443" + volumes: + - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro + - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro \ No newline at end of file diff --git a/src/docker-compose.yml b/src/docker-compose.yml new file mode 100644 index 0000000..d252ac1 --- /dev/null +++ b/src/docker-compose.yml @@ -0,0 +1,18 @@ +version: '3.4' + +services: + mars.web: + image: ${DOCKER_REGISTRY-}marsweb + build: + context: . + dockerfile: Mars.Web/Dockerfile + + seq: + image: datalust/seq:latest + container_name: seq + ports: + - "8888:80" + volumes: + - /datadrive:/data + environment: + - ACCEPT_EULA=Y \ No newline at end of file From 8872ab958b381e2b07a85e1958c1022041049987 Mon Sep 17 00:00:00 2001 From: garv5014 Date: Wed, 15 Feb 2023 12:36:33 -0700 Subject: [PATCH 11/21] adjusted the using scopes --- src/Mars.Web/Controllers/GameController.cs | 36 ++++++++++++---------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/Mars.Web/Controllers/GameController.cs b/src/Mars.Web/Controllers/GameController.cs index 5f35bf7..51f9341 100644 --- a/src/Mars.Web/Controllers/GameController.cs +++ b/src/Mars.Web/Controllers/GameController.cs @@ -33,7 +33,7 @@ public ActionResult Join(string gameId, string name) var joinResult = gameManager.Game.Join(name); tokenMap.TryAdd(joinResult.Token.Value, gameId); - using (logger.BeginScope("User: {ScopeUser} GameId: {ScopeGameId} ", joinResult.Token.Value, gameId)) + using (logger.BeginScope("ScopeUserToken: {ScopeUser} GameId: {ScopeGameId} ", joinResult.Token.Value, gameId)) { logger.LogInformation($"Player {name} joined game {gameId}"); } @@ -66,18 +66,19 @@ public ActionResult Join(string gameId, string name) [ProducesResponseType(StatusCodes.Status400BadRequest)] public ActionResult Status(string token) { - if (tokenMap.TryGetValue(token, out string? gameId)) + var tokenHasGame = tokenMap.TryGetValue(token, out string? gameId); + using (logger.BeginScope("ScopeUserToken: {ScopeUser} GameId: {ScopeGameId} ", token, gameId)) { - if (games.TryGetValue(gameId, out var gameManager)) + if (tokenHasGame) { - if (gameManager.Game.TryTranslateToken(token, out _)) + if (games.TryGetValue(gameId, out var gameManager)) { - return new StatusResponse { Status = gameManager.Game.GameState.ToString() }; + if (gameManager.Game.TryTranslateToken(token, out _)) + { + return new StatusResponse { Status = gameManager.Game.GameState.ToString() }; + } } } - } - using (logger.BeginScope("User: {ScopeUser} GameId: {ScopeGameId} ", token, gameId)) - { logger.LogError($"Unrecogized token {token}"); return Problem("Unrecognized token", statusCode: 400, title: "Bad Token"); } @@ -93,9 +94,11 @@ public ActionResult Status(string token) [ProducesResponseType(StatusCodes.Status400BadRequest)] public ActionResult MovePerseverance(string token, Direction direction) { - if (tokenMap.TryGetValue(token, out string? gameId)) + var tokenHasGame = tokenMap.TryGetValue(token, out string? gameId); + + using (logger.BeginScope("ScopeUserToken: {ScopeUser} GameId: {ScopeGameId} ", token, gameId)) { - using (logger.BeginScope("User: {ScopeUser} GameId: {ScopeGameId} ", token, gameId)) + if (tokenHasGame) { if (games.TryGetValue(gameId, out var gameManager)) { @@ -133,9 +136,9 @@ public ActionResult MovePerseverance(string token, Direction direc } } + logger.LogError($"Unrecogized token {token}"); + return Problem("Unrecognized token", statusCode: 400, title: "Bad Token"); } - logger.LogError($"Unrecogized token {token}"); - return Problem("Unrecognized token", statusCode: 400, title: "Bad Token"); } /// @@ -149,9 +152,10 @@ public ActionResult MovePerseverance(string token, Direction direc [ProducesResponseType(StatusCodes.Status400BadRequest)] public ActionResult MoveIngenuity(string token, int destinationRow, int destinationColumn) { - if (tokenMap.TryGetValue(token, out string? gameId)) + var tokenHasGame = tokenMap.TryGetValue(token, out string? gameId); + using (logger.BeginScope("ScopeUserToken: {ScopeUser} GameId: {ScopeGameId} ", token, gameId)) { - using (logger.BeginScope("User: {ScopeUser} GameId: {ScopeGameId} ", token, gameId)) + if (tokenHasGame) { if (games.TryGetValue(gameId, out var gameManager)) { @@ -187,8 +191,8 @@ public ActionResult MoveIngenuity(string token, int desti } } } + logger.LogError($"Unrecogized token {token}"); + return Problem("Unrecognized token", statusCode: 400, title: "Bad Token"); } - logger.LogError($"Unrecogized token {token}"); - return Problem("Unrecognized token", statusCode: 400, title: "Bad Token"); } } From 7e581021eb87f9250dbcd68ccd4641a6dd37a549 Mon Sep 17 00:00:00 2001 From: garv5014 Date: Wed, 15 Feb 2023 12:45:01 -0700 Subject: [PATCH 12/21] adjusted the using scopes --- src/Mars.Web/Controllers/GameController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Mars.Web/Controllers/GameController.cs b/src/Mars.Web/Controllers/GameController.cs index 51f9341..16a665c 100644 --- a/src/Mars.Web/Controllers/GameController.cs +++ b/src/Mars.Web/Controllers/GameController.cs @@ -32,9 +32,9 @@ public ActionResult Join(string gameId, string name) { var joinResult = gameManager.Game.Join(name); - tokenMap.TryAdd(joinResult.Token.Value, gameId); using (logger.BeginScope("ScopeUserToken: {ScopeUser} GameId: {ScopeGameId} ", joinResult.Token.Value, gameId)) { + tokenMap.TryAdd(joinResult.Token.Value, gameId); logger.LogInformation($"Player {name} joined game {gameId}"); } return new JoinResponse From d3c1f179a01f7456f2ae2b48d80d29a7e01e5b38 Mon Sep 17 00:00:00 2001 From: Breanna Nesbit Date: Wed, 15 Feb 2023 20:17:27 -0700 Subject: [PATCH 13/21] added docker compose/container --- src/.dockerignore | 25 +++++++++++++++ src/Mars.Web/Dockerfile | 24 ++++++++++++++ src/Mars.Web/Mars.Web.csproj | 3 ++ src/Mars.Web/Properties/launchSettings.json | 35 +++++++++++++-------- src/MarsRover.sln | 6 ++++ src/docker-compose.dcproj | 18 +++++++++++ src/docker-compose.override.yml | 13 ++++++++ src/docker-compose.yml | 20 ++++++++++++ 8 files changed, 131 insertions(+), 13 deletions(-) create mode 100644 src/.dockerignore create mode 100644 src/Mars.Web/Dockerfile create mode 100644 src/docker-compose.dcproj create mode 100644 src/docker-compose.override.yml create mode 100644 src/docker-compose.yml diff --git a/src/.dockerignore b/src/.dockerignore new file mode 100644 index 0000000..3729ff0 --- /dev/null +++ b/src/.dockerignore @@ -0,0 +1,25 @@ +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/azds.yaml +**/bin +**/charts +**/docker-compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md \ No newline at end of file diff --git a/src/Mars.Web/Dockerfile b/src/Mars.Web/Dockerfile new file mode 100644 index 0000000..04e40d9 --- /dev/null +++ b/src/Mars.Web/Dockerfile @@ -0,0 +1,24 @@ +#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging. + +FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base +WORKDIR /app +EXPOSE 80 +EXPOSE 443 + +FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build +WORKDIR /src +COPY ["Mars.Web/Mars.Web.csproj", "Mars.Web/"] +COPY ["Mars.MissionControl/Mars.MissionControl.csproj", "Mars.MissionControl/"] +COPY ["Mars.Web.Types/Mars.Web.Types.csproj", "Mars.Web.Types/"] +RUN dotnet restore "Mars.Web/Mars.Web.csproj" +COPY . . +WORKDIR "/src/Mars.Web" +RUN dotnet build "Mars.Web.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "Mars.Web.csproj" -c Release -o /app/publish /p:UseAppHost=false + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "Mars.Web.dll"] \ No newline at end of file diff --git a/src/Mars.Web/Mars.Web.csproj b/src/Mars.Web/Mars.Web.csproj index fc67c6f..d1591f5 100644 --- a/src/Mars.Web/Mars.Web.csproj +++ b/src/Mars.Web/Mars.Web.csproj @@ -6,6 +6,8 @@ enable 1c3d0055-a8d7-4fc1-a151-6dbc7e1b1d38 True + Linux + ..\docker-compose.dcproj @@ -17,6 +19,7 @@ + diff --git a/src/Mars.Web/Properties/launchSettings.json b/src/Mars.Web/Properties/launchSettings.json index 29d99f9..9f091b1 100644 --- a/src/Mars.Web/Properties/launchSettings.json +++ b/src/Mars.Web/Properties/launchSettings.json @@ -1,28 +1,22 @@ { - "iisSettings": { - "iisExpress": { - "applicationUrl": "http://localhost:26097", - "sslPort": 44335 - } - }, "profiles": { "http": { "commandName": "Project", - "dotnetRunMessages": true, "launchBrowser": true, - "applicationUrl": "http://localhost:5110", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" - } + }, + "dotnetRunMessages": true, + "applicationUrl": "http://localhost:5110" }, "https": { "commandName": "Project", - "dotnetRunMessages": true, "launchBrowser": true, - "applicationUrl": "https://localhost:7287;http://localhost:5110", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" - } + }, + "dotnetRunMessages": true, + "applicationUrl": "https://localhost:7287;http://localhost:5110" }, "IIS Express": { "commandName": "IISExpress", @@ -30,6 +24,21 @@ "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } + }, + "Docker": { + "commandName": "Docker", + "launchBrowser": true, + "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}", + "publishAllPorts": true, + "useSSL": true + } + }, + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:26097", + "sslPort": 44335 } } -} +} \ No newline at end of file diff --git a/src/MarsRover.sln b/src/MarsRover.sln index b76f6cf..503f471 100644 --- a/src/MarsRover.sln +++ b/src/MarsRover.sln @@ -13,6 +13,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mars.Web.Tests", "Mars.Web. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mars.Web.Types", "Mars.Web.Types\Mars.Web.Types.csproj", "{A92385B4-ADF1-4201-970E-915A57426B5D}" EndProject +Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{687118E8-8269-4BA9-93B1-CDCA4A310CC1}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -39,6 +41,10 @@ Global {A92385B4-ADF1-4201-970E-915A57426B5D}.Debug|Any CPU.Build.0 = Debug|Any CPU {A92385B4-ADF1-4201-970E-915A57426B5D}.Release|Any CPU.ActiveCfg = Release|Any CPU {A92385B4-ADF1-4201-970E-915A57426B5D}.Release|Any CPU.Build.0 = Release|Any CPU + {687118E8-8269-4BA9-93B1-CDCA4A310CC1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {687118E8-8269-4BA9-93B1-CDCA4A310CC1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {687118E8-8269-4BA9-93B1-CDCA4A310CC1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {687118E8-8269-4BA9-93B1-CDCA4A310CC1}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/docker-compose.dcproj b/src/docker-compose.dcproj new file mode 100644 index 0000000..3aa38d0 --- /dev/null +++ b/src/docker-compose.dcproj @@ -0,0 +1,18 @@ + + + + 2.1 + Linux + 687118e8-8269-4ba9-93b1-cdca4a310cc1 + LaunchBrowser + {Scheme}://localhost:{ServicePort} + mars.web + + + + docker-compose.yml + + + + + \ No newline at end of file diff --git a/src/docker-compose.override.yml b/src/docker-compose.override.yml new file mode 100644 index 0000000..e5856f2 --- /dev/null +++ b/src/docker-compose.override.yml @@ -0,0 +1,13 @@ +version: '3.4' + +services: + mars.web: + environment: + - ASPNETCORE_ENVIRONMENT=Development + - ASPNETCORE_URLS=https://+:443;http://+:80 + ports: + - "80" + - "443" + volumes: + - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro + - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro \ No newline at end of file diff --git a/src/docker-compose.yml b/src/docker-compose.yml new file mode 100644 index 0000000..818a468 --- /dev/null +++ b/src/docker-compose.yml @@ -0,0 +1,20 @@ +version: '3.4' + +services: + mars.web: + image: ${DOCKER_REGISTRY-}marsweb + build: + context: . + dockerfile: Mars.Web/Dockerfile + + seq: + container_name: seq + image: datalust/seq:latest + ports: + - "8888:5341" + - "8075:80" + - "45341:45341" + volumes: + - /datadrive:/data + environment: + - ACCEPT_EUL=Y \ No newline at end of file From 862f587317737897f4174c003a31ef0557518cac Mon Sep 17 00:00:00 2001 From: Caleb Wightman Date: Wed, 15 Feb 2023 22:51:17 -0700 Subject: [PATCH 14/21] added loggin for winning --- src/Mars.MissionControl/Game.cs | 14 +++++++++----- src/Mars.MissionControl/Mars.MissionControl.csproj | 4 ++++ src/Mars.Web/GameManager.cs | 12 +++++++----- src/Mars.Web/MultiGameHoster.cs | 12 +++++++----- 4 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/Mars.MissionControl/Game.cs b/src/Mars.MissionControl/Game.cs index 27c359f..e0877e9 100644 --- a/src/Mars.MissionControl/Game.cs +++ b/src/Mars.MissionControl/Game.cs @@ -1,9 +1,10 @@ -using System.Collections.ObjectModel; +using Microsoft.Extensions.Logging; +using System.Collections.ObjectModel; namespace Mars.MissionControl; public class Game : IDisposable { - public Game(GameStartOptions startOptions) + public Game(GameStartOptions startOptions, ILoggerFactory loggerFactory = null) { GameState = GameState.Joining; Board = new Board(startOptions.Map); @@ -12,7 +13,8 @@ public Game(GameStartOptions startOptions) PerseveranceVisibilityRadius = startOptions.PerseveranceVisibilityRadius; IngenuityVisibilityRadius = startOptions.IngenuityVisibilityRadius; StartingBatteryLevel = startOptions.StartingBatteryLevel; - IngenuityStartingBatteryLevel = Board.Width * 2 + Board.Height * 2; + IngenuityStartingBatteryLevel = Board.Width * 2 + Board.Height * 2; + this.logger = loggerFactory.CreateLogger(); } public int MapNumber => Board.MapNumber; @@ -40,7 +42,9 @@ public Game(GameStartOptions startOptions) #region State Changed public event EventHandler? GameStateChanged; public DateTime lastStateChange; - public TimeSpan stateChangeFrequency;// = TimeSpan.FromSeconds(1); + public TimeSpan stateChangeFrequency;// = TimeSpan.FromSeconds(1); + private readonly ILogger logger; + private void raiseStateChange() { if (lastStateChange + stateChangeFrequency < DateTime.Now) @@ -242,7 +246,7 @@ public MoveResult MovePerseverance(PlayerToken token, Direction direction) if (player.PerseveranceLocation == TargetLocation)//you win! { - + logger.LogInformation("Player {0} has won!", player.Name); players.Remove(player.Token, out _); player = player with { WinningTime = DateTime.Now - GameStartedOn }; winners.Enqueue(player); diff --git a/src/Mars.MissionControl/Mars.MissionControl.csproj b/src/Mars.MissionControl/Mars.MissionControl.csproj index a1ed5b3..1ab1a63 100644 --- a/src/Mars.MissionControl/Mars.MissionControl.csproj +++ b/src/Mars.MissionControl/Mars.MissionControl.csproj @@ -6,4 +6,8 @@ enable + + + + diff --git a/src/Mars.Web/GameManager.cs b/src/Mars.Web/GameManager.cs index 6c13148..fa3c0a5 100644 --- a/src/Mars.Web/GameManager.cs +++ b/src/Mars.Web/GameManager.cs @@ -3,16 +3,18 @@ namespace Mars.Web; public class GameManager -{ - public GameManager(List maps) +{ + private readonly ILoggerFactory logger; + + public GameManager(List maps, ILoggerFactory logger = null) { CreatedOn = DateTime.Now; GameStartOptions = new GameStartOptions { Map = maps[0], }; - this.Maps = maps; - + this.Maps = maps; + this.logger = logger; StartNewGame(GameStartOptions); } public IReadOnlyList Maps { get; } @@ -55,7 +57,7 @@ public void StartNewGame(GameStartOptions startOptions) NewGameStarted?.Invoke(this, new EventArgs()); - Game = new Game(startOptions); + Game = new Game(startOptions, logger); GameStateChanged?.Invoke(this, EventArgs.Empty); //subscribe to new event diff --git a/src/Mars.Web/MultiGameHoster.cs b/src/Mars.Web/MultiGameHoster.cs index 610be05..fb419c3 100644 --- a/src/Mars.Web/MultiGameHoster.cs +++ b/src/Mars.Web/MultiGameHoster.cs @@ -4,10 +4,11 @@ public class MultiGameHoster { - public MultiGameHoster(IMapProvider mapProvider, ILogger logger) + public MultiGameHoster(IMapProvider mapProvider, ILogger logger, ILoggerFactory loggerFactory) { ParsedMaps = new List(mapProvider.LoadMaps()); - this.logger = logger; + this.logger = logger; + this.loggerFactory = loggerFactory; } public void RaiseOldGamesPurged() => OldGamesPurged?.Invoke(this, EventArgs.Empty); @@ -19,14 +20,15 @@ public MultiGameHoster(IMapProvider mapProvider, ILogger logger private string nextGame = "a"; private object lockObject = new(); private readonly IWebHostEnvironment hostEnvironment; - private readonly ILogger logger; - + private readonly ILogger logger; + private readonly ILoggerFactory loggerFactory; + public string MakeNewGame() { lock (lockObject) { var gameId = nextGame; - Games.TryAdd(gameId, new GameManager(ParsedMaps)); + Games.TryAdd(gameId, new GameManager(ParsedMaps, loggerFactory)); nextGame = IncrementGameId(nextGame); logger.LogInformation($"New Game Created: {gameId}"); From ed01c4bb72d3d6e8d3afdd9e1a45e0c7596566c4 Mon Sep 17 00:00:00 2001 From: Jonathan Allen Date: Tue, 21 Feb 2023 10:59:28 -0700 Subject: [PATCH 15/21] update github actions to run dotnet test MarsRover.sln --- .github/workflows/deploy-main-branch.yaml | 2 +- .github/workflows/deploy-pull-request.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy-main-branch.yaml b/.github/workflows/deploy-main-branch.yaml index d2c8dad..8538323 100644 --- a/.github/workflows/deploy-main-branch.yaml +++ b/.github/workflows/deploy-main-branch.yaml @@ -31,7 +31,7 @@ jobs: - name: Run Tests working-directory: src - run: dotnet test + run: dotnet test MarsRover.sln - name: dotnet publish working-directory: src/Mars.Web diff --git a/.github/workflows/deploy-pull-request.yaml b/.github/workflows/deploy-pull-request.yaml index 2b0c231..198a3a8 100644 --- a/.github/workflows/deploy-pull-request.yaml +++ b/.github/workflows/deploy-pull-request.yaml @@ -33,7 +33,7 @@ jobs: - name: Run Tests working-directory: src - run: dotnet test + run: dotnet test MarsRover.sln - name: dotnet publish working-directory: src/Mars.Web From d08a28a55af687126584ad32109e87abcaa0252d Mon Sep 17 00:00:00 2001 From: Jonathan Allen Date: Thu, 23 Feb 2023 15:23:09 -0700 Subject: [PATCH 16/21] add jaeger/distributed tracing --- src/Mars.Web/Controllers/GameController.cs | 11 +++++++---- src/Mars.Web/Mars.Web.csproj | 3 +++ src/Mars.Web/Program.cs | 21 +++++++++++++++++---- src/docker-compose.yml | 21 ++++++++++++++++++++- 4 files changed, 47 insertions(+), 9 deletions(-) diff --git a/src/Mars.Web/Controllers/GameController.cs b/src/Mars.Web/Controllers/GameController.cs index 6545e19..be765c8 100644 --- a/src/Mars.Web/Controllers/GameController.cs +++ b/src/Mars.Web/Controllers/GameController.cs @@ -1,9 +1,12 @@ -using Mars.MissionControl; -using Mars.Web.Pages; -using Microsoft.AspNetCore.Mvc; +using System.Diagnostics; namespace Mars.Web.Controllers; +public static class GameActivitySource +{ + public static ActivitySource Instance { get; } = new ActivitySource("Mars.Web", "1.0"); +} + [ApiController] [Route("[controller]")] public class GameController : ControllerBase @@ -34,7 +37,7 @@ public ActionResult Join(string gameId, string name) { try { - + using var activity = GameActivitySource.Instance.StartActivity("Join Game"); var joinResult = gameManager.Game.Join(name); using (logger.BeginScope("ScopeUserToken: {ScopeUser} GameId: {ScopeGameId} ", joinResult.Token.Value, gameId)) { diff --git a/src/Mars.Web/Mars.Web.csproj b/src/Mars.Web/Mars.Web.csproj index d3bcd5f..16fb7ba 100644 --- a/src/Mars.Web/Mars.Web.csproj +++ b/src/Mars.Web/Mars.Web.csproj @@ -21,6 +21,9 @@ + + + diff --git a/src/Mars.Web/Program.cs b/src/Mars.Web/Program.cs index 423186a..253bbda 100644 --- a/src/Mars.Web/Program.cs +++ b/src/Mars.Web/Program.cs @@ -1,17 +1,30 @@ +using Hellang.Middleware.ProblemDetails; using Mars.Web; +using Mars.Web.Controllers; using Microsoft.OpenApi.Models; +using OpenTelemetry; +using OpenTelemetry.Resources; +using OpenTelemetry.Trace; using Serilog; using Serilog.Exceptions; using System.Reflection; -using System.Runtime.InteropServices; using System.Text.Json.Serialization; using System.Threading.RateLimiting; -using Hellang.Middleware.ProblemDetails; -using Serilog; -using Serilog.Exceptions; var builder = WebApplication.CreateBuilder(args); +using var traceProvider = Sdk.CreateTracerProviderBuilder() + .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("Mars.Web")) + .AddSource(GameActivitySource.Instance.Name) + .AddJaegerExporter(o => + { + o.Protocol = OpenTelemetry.Exporter.JaegerExportProtocol.HttpBinaryThrift; + o.Endpoint = new Uri("http://jaeger:14268/api/traces"); + }) + .AddHttpClientInstrumentation() + .AddAspNetCoreInstrumentation() + .Build(); + builder.Host.UseSerilog((c, l) => { l.WriteTo.Console() diff --git a/src/docker-compose.yml b/src/docker-compose.yml index 1bbee0e..53459be 100644 --- a/src/docker-compose.yml +++ b/src/docker-compose.yml @@ -8,6 +8,8 @@ services: dockerfile: Mars.Web/Dockerfile environment: - SeqServer=http://seq + networks: + - jaegernet seq: container_name: seq @@ -17,4 +19,21 @@ services: volumes: - /datadrive:/data environment: - - ACCEPT_EULA=Y \ No newline at end of file + - ACCEPT_EULA=Y + + jaeger: + container_name: jaeger + image: jaegertracing/all-in-one:latest + ports: + - "16686:16686" + - "14268:14268" + environment: + - COLLECTOR_OTLP_ENABLED=true + - LOG_LEVEL=debug + networks: + - jaegernet + depends_on: + - mars.web + +networks: + jaegernet: \ No newline at end of file From 4269609db113cda4595b96fa8ce1aa3b77e5b15b Mon Sep 17 00:00:00 2001 From: Jonathan Allen Date: Thu, 23 Feb 2023 15:29:26 -0700 Subject: [PATCH 17/21] stop running codeql --- .github/workflows/{codeql.yml => codeql.yml.bogus} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{codeql.yml => codeql.yml.bogus} (100%) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml.bogus similarity index 100% rename from .github/workflows/codeql.yml rename to .github/workflows/codeql.yml.bogus From 1cf21c82ff930ce5a66a0499ba5d36e82b304f73 Mon Sep 17 00:00:00 2001 From: Jonathan Allen Date: Thu, 23 Feb 2023 15:31:38 -0700 Subject: [PATCH 18/21] only use serilog once --- src/Mars.Web/Program.cs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/Mars.Web/Program.cs b/src/Mars.Web/Program.cs index 253bbda..dd23052 100644 --- a/src/Mars.Web/Program.cs +++ b/src/Mars.Web/Program.cs @@ -25,13 +25,6 @@ .AddAspNetCoreInstrumentation() .Build(); -builder.Host.UseSerilog((c, l) => -{ - l.WriteTo.Console() - .Enrich.WithExceptionDetails() - .WriteTo.Seq("http://seq"); -}); - builder.Services.AddApplicationInsightsTelemetry(); builder.Services.AddRazorPages(); builder.Services.AddServerSideBlazor(); From 12d9ddb5e2e5fd07fd63745a554aee3c5435f42d Mon Sep 17 00:00:00 2001 From: Jonathan Allen Date: Thu, 23 Feb 2023 15:52:37 -0700 Subject: [PATCH 19/21] add extra app insights collection --- src/Mars.Web/Mars.Web.csproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Mars.Web/Mars.Web.csproj b/src/Mars.Web/Mars.Web.csproj index 16fb7ba..90e2efe 100644 --- a/src/Mars.Web/Mars.Web.csproj +++ b/src/Mars.Web/Mars.Web.csproj @@ -19,7 +19,11 @@ + + + + From d7e4c4ed415fb3bb821b7aeb85ce372d4a3e5b40 Mon Sep 17 00:00:00 2001 From: Jonathan Allen Date: Thu, 23 Feb 2023 16:17:05 -0700 Subject: [PATCH 20/21] see logs in app insights? --- src/Mars.Web/Controllers/GameController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Mars.Web/Controllers/GameController.cs b/src/Mars.Web/Controllers/GameController.cs index be765c8..1bd0a81 100644 --- a/src/Mars.Web/Controllers/GameController.cs +++ b/src/Mars.Web/Controllers/GameController.cs @@ -42,7 +42,7 @@ public ActionResult Join(string gameId, string name) using (logger.BeginScope("ScopeUserToken: {ScopeUser} GameId: {ScopeGameId} ", joinResult.Token.Value, gameId)) { tokenMap.TryAdd(joinResult.Token.Value, gameId); - logger.LogInformation("Player {name} joined game {gameId}", name, gameId); + logger.LogWarning("Player {name} joined game {gameId}", name, gameId); } return new JoinResponse { From 3235bf2265da1153a74a7437511067db6065e80c Mon Sep 17 00:00:00 2001 From: Jonathan Allen Date: Thu, 23 Feb 2023 16:36:09 -0700 Subject: [PATCH 21/21] try changing config there --- src/Mars.Web/appsettings.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Mars.Web/appsettings.json b/src/Mars.Web/appsettings.json index 636bf8a..bac4d64 100644 --- a/src/Mars.Web/appsettings.json +++ b/src/Mars.Web/appsettings.json @@ -4,6 +4,11 @@ "Default": "Information", "Microsoft.AspNetCore": "Warning" }, + "ApplicationInsights": { + "LogLevel": { + "Default": "Information" + } + }, "Console": { "FormatterName": "json", "FormatterOptions": {