7 Commits

Author SHA1 Message Date
Gardient
de6becc208 adds debug logging 2016-11-15 14:48:41 +02:00
gardient
917624ad52 Adds license file 2016-11-10 14:04:19 +02:00
Gardient
e9c060cd0d #1 - fixes ignored command line argument 2016-11-10 13:47:37 +02:00
Gardient
acf3f8c0fe Updates README.md 2016-10-27 15:59:05 +03:00
Gardient
ea09bd6b19 Merge branch 'master' of github.com:gardient/CloudWatchLogDownloader 2016-10-27 15:53:58 +03:00
Gardient
2bfa977d99 Adds support for livestreaming logstreams 2016-10-27 15:51:04 +03:00
gardient
ddbfa25f8e Create README.md 2016-10-21 14:58:25 +03:00
6 changed files with 178 additions and 8 deletions

View File

@@ -56,6 +56,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="DebugLogger.cs" />
<Compile Include="Models\CommandOptions.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />

View File

@@ -0,0 +1,87 @@
using System;
namespace CloudWatchLogDownloader
{
internal static class DebugLogger
{
private static bool _debug;
public static bool Debug
{
get { return _debug; }
set
{
if (value && !_debug)
{
WriteLine("debug mode active");
}
_debug = value;
}
}
public static void Write(string str)
{
if (_debug)
{
var oldcolor = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Cyan;
Console.Write(str);
Console.ForegroundColor = oldcolor;
}
}
public static void Write(object obj)
{
if (_debug)
{
var oldcolor = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Cyan;
Console.Write(obj);
Console.ForegroundColor = oldcolor;
}
}
public static void Write(string format, params object[] args)
{
if (_debug)
{
var oldcolor = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Cyan;
Console.Write(format, args);
Console.ForegroundColor = oldcolor;
}
}
public static void WriteLine(string str)
{
if (_debug)
{
var oldcolor = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine(str);
Console.ForegroundColor = oldcolor;
}
}
public static void WriteLine(object obj)
{
if (_debug)
{
var oldcolor = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine(obj);
Console.ForegroundColor = oldcolor;
}
}
public static void WriteLine(string format, params object[] args)
{
if (_debug)
{
var oldcolor = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine(format, args);
Console.ForegroundColor = oldcolor;
}
}
}
}

View File

@@ -17,6 +17,12 @@ namespace CloudWatchLogDownloader.Models
[ValueOption(2)]
public string OutputFilePath { get; set; }
[Option('l', "liveStream", HelpText="Keep pulling logs until Ctrl+C is applied")]
public bool LiveStream { get; set; }
[Option('d',"debug", HelpText = "print additional logs to console")]
public bool Debug { get; set; }
[ParserState]
public IParserState ParserState { get; set; }

View File

@@ -16,10 +16,12 @@ namespace CloudWatchLogDownloader
var opt = new CommandOptions();
if (CommandLine.Parser.Default.ParseArguments(args, opt))
{
DebugLogger.Debug = opt.Debug;
client = new AmazonCloudWatchLogsClient();
var logGroup = GetLogGroup(opt.LogGroup);
var logStream = GetLogStream(logGroup, opt.LogStream);
WriteLogToFile(logGroup, logStream, opt.OutputFilePath);
WriteLogToFile(logGroup, logStream, opt.LiveStream, opt.OutputFilePath);
}
}
@@ -29,8 +31,10 @@ namespace CloudWatchLogDownloader
DescribeLogGroupsResponse lgResponse = null;
do
{
DebugLogger.WriteLine("Getting logGroups...");
lgResponse = client.DescribeLogGroups(new DescribeLogGroupsRequest { NextToken = (lgResponse != null ? lgResponse.NextToken : null) });
allGroups.AddRange(lgResponse.LogGroups);
DebugLogger.WriteLine("Got logGroups, have {0}, {1} more pages", allGroups.Count, (!string.IsNullOrWhiteSpace(lgResponse.NextToken) ? "still" : "no"));
} while (!string.IsNullOrWhiteSpace(lgResponse.NextToken));
if (string.IsNullOrWhiteSpace(logGroup) || logGroup[logGroup.Length - 1] == '*')
@@ -64,12 +68,14 @@ namespace CloudWatchLogDownloader
DescribeLogStreamsResponse lsResponse = null;
do
{
DebugLogger.WriteLine("Getting logStreams...");
lsResponse = client.DescribeLogStreams(new DescribeLogStreamsRequest
{
NextToken = (lsResponse != null ? lsResponse.NextToken : null),
LogGroupName = logGroup.LogGroupName
});
allStreams.AddRange(lsResponse.LogStreams);
DebugLogger.WriteLine("Got logStreams, have {0}, {1} more pages", allStreams.Count, (!string.IsNullOrWhiteSpace(lsResponse.NextToken) ? "still" : "no"));
} while (!string.IsNullOrWhiteSpace(lsResponse.NextToken));
if (string.IsNullOrWhiteSpace(logStream) || logStream[logStream.Length - 1] == '*')
@@ -80,7 +86,7 @@ namespace CloudWatchLogDownloader
allStreams = allStreams.Where(x => x.LogStreamName.StartsWith(logStream)).ToList();
}
allStreams = allStreams.OrderBy(x => x.CreationTime).ToList();
allStreams = allStreams.OrderByDescending(x => x.CreationTime).ToList();
for (int i = 0, len = allStreams.Count; i < len; ++i)
Console.WriteLine(i + ") " + allStreams[i].LogStreamName);
@@ -99,20 +105,34 @@ namespace CloudWatchLogDownloader
return ls;
}
private static void WriteLogToFile(LogGroup logGroup, LogStream logStream, string outputFilePath = null)
private static void WriteLogToFile(LogGroup logGroup, LogStream logStream, bool liveStream, string outputFilePath = null)
{
Console.WriteLine("Choose Output file [logs/" + logStream.LogStreamName + ".log]: ");
var output = Console.ReadLine();
if (string.IsNullOrWhiteSpace(output))
output = "logs/" + logStream.LogStreamName + ".log";
string output = null;
if (string.IsNullOrWhiteSpace(outputFilePath))
{
Console.WriteLine("Choose Output file [logs/" + logStream.LogStreamName + ".log]: ");
output = Console.ReadLine();
if (string.IsNullOrWhiteSpace(output))
output = "logs/" + logStream.LogStreamName + ".log";
}
else
{
output = outputFilePath;
}
if (!Directory.GetParent(output).Exists)
Directory.CreateDirectory(Directory.GetParent(output).FullName);
Console.WriteLine("Downloading log into " + output);
bool lsMessage = !liveStream;
using (StreamWriter sw = new StreamWriter(output))
{
GetLogEventsResponse leResponse = null;
do
{
DebugLogger.WriteLine("Getting events...");
leResponse = client.GetLogEvents(new GetLogEventsRequest
{
LogGroupName = logGroup.LogGroupName,
@@ -120,12 +140,23 @@ namespace CloudWatchLogDownloader
StartFromHead = true,
NextToken = (leResponse != null ? leResponse.NextForwardToken : null)
});
DebugLogger.WriteLine("Got {0} events", leResponse.Events.Count);
foreach (var ev in leResponse.Events)
sw.WriteLine(ev.Message);
sw.Flush();
} while (leResponse.NextForwardToken != null && leResponse.Events.Any());
if (!leResponse.Events.Any() && !lsMessage && liveStream)
{
lsMessage = true;
ConsoleColor oldcolor = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("Now streaming live from lg: " + logGroup.LogGroupName + " ls: " + logStream.LogStreamName + " into " + output);
Console.ForegroundColor = oldcolor;
Console.WriteLine("{0}{0}Press CTRL+C to stop...", Environment.NewLine);
}
} while ((leResponse.NextForwardToken != null && leResponse.Events.Any()) || liveStream);
}
}

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2016 gardient
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

24
README.md Normal file
View File

@@ -0,0 +1,24 @@
# CloudWatchLogDownloader
Download full logs from AWS CloudWatch
## Who is it for?
For idiots like me who just want a text dump of the cloud watch log without going through S3
## Why .NET?
Because I was working with the .NET AWSSDK when writing this.
## Why not .NET CORE?
Because the AWSSDK.CloudWatchLogs nuget package doesn't support it. (As of writing this README)
## Usage
If you're still reading this means you want to use this abomination... Good.
### Command line params
|short|long|Description|
|-----|----|-----------|
|-g|--logGroup|The log group you want to select the stream from, can end with '*' in which case the option to choose from all groups starting with this will be given|
|-s|--logStream|The log stream you want to save, can end with '*' in which case the option to choose from all groups starting with this will be given|
|-o|--outputFile|The file to output the logs to.|
|-l|--liveStream|After reaching the newest log keep polling until ctrl+c is pressed|
If any of the above are not specified the program will prompt for them