15 October 2013 Azure, Azure Websites, FTP, HowTo Robert Muehsig

Websites auf Azure legen Diagnoseinformationen (Fehler Berichte, IIS Logs, Git Logs oder eigene Logfiles) als Text-Datei auf dem Server ab. Diese lassen sich relativ einfach via FTP auslesen. Der FTP Endpunkt für eine Website in West-Europa sollte dieser sei:

ftp://waws-prod-am2-001.ftp.azurewebsites.windows.net

Zu sehen ist die natürlich auch im Azure Management:

image

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Programmatischer Zugriff

Um die Logs weiterzuverarbeiten kann man diese natürlich auch programmatisch herunterladen – der FTP Zugriff ist ja schon relativ lang im .NET Framework möglich. Allerdings hatte ich nie was damit zutun, sodass es für eine Premiere war ;)

Der Code stamt zum großen Teil aus diesem MSDN Forenbeitrag.

   1: class Program
   2:     {
   3:         static void Main(string[] args)
   4:         {
   5:             const string userName = "SITENAME\\ACC";
   6:             const string password = "PW";
   7:             const string ftpPath = "ftp://waws-prod-am2-001.ftp.azurewebsites.windows.net/LogFiles/http/RawLogs/";
   8:             const string destinationPath = @"C:\Users\Foobar\Buzz\Demo";
   9:  
  10:  
  11:             string[] files = GetFileListFromFtp(ftpPath, userName, password);
  12:             foreach (string file in files)
  13:             {
  14:                 Console.WriteLine("Download File {0} from FTP.", file);
  15:                 DownloadSingleFileFromFtp(ftpPath, file, destinationPath, userName, password);
  16:             }
  17:  
  18:             Console.WriteLine("And done...");
  19:  
  20:             Console.ReadLine();
  21:         }
  22:  
  23:  
  24:         public static string[] GetFileListFromFtp(string path, string userName, string password)
  25:         {
  26:             var result = new StringBuilder();
  27:             WebResponse response = null;
  28:             StreamReader reader = null;
  29:             try
  30:             {
  31:                 var reqFTP = (FtpWebRequest)WebRequest.Create(new Uri(path));
  32:                 reqFTP.UseBinary = true;
  33:                 reqFTP.Credentials = new NetworkCredential(userName, password);
  34:                 reqFTP.Method = WebRequestMethods.Ftp.ListDirectory;
  35:                 reqFTP.Proxy = null;
  36:                 reqFTP.KeepAlive = false;
  37:                 reqFTP.UsePassive = false;
  38:                 response = reqFTP.GetResponse();
  39:                 reader = new StreamReader(response.GetResponseStream());
  40:                 string line = reader.ReadLine();
  41:                 while (line != null)
  42:                 {
  43:                     result.Append(line);
  44:                     result.Append("\n");
  45:                     line = reader.ReadLine();
  46:                 }
  47:                 // to remove the trailing '\n'
  48:                 result.Remove(result.ToString().LastIndexOf('\n'), 1);
  49:                 return result.ToString().Split('\n');
  50:             }
  51:             catch (Exception)
  52:             {
  53:                 if (reader != null)
  54:                 {
  55:                     reader.Close();
  56:                 }
  57:                 if (response != null)
  58:                 {
  59:                     response.Close();
  60:                 }
  61:  
  62:                 throw;
  63:             }
  64:         }
  65:  
  66:         public static void DownloadSingleFileFromFtp(string sourcePath, string file, string destinationPath, string userName, string password)
  67:         {
  68:             var reqFTP = (FtpWebRequest)WebRequest.Create(new Uri(sourcePath + file));
  69:             reqFTP.Credentials = new NetworkCredential(userName, password);
  70:             reqFTP.KeepAlive = false;
  71:             reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
  72:             reqFTP.UseBinary = true;
  73:             reqFTP.Proxy = null;
  74:             reqFTP.UsePassive = false;
  75:             var response = (FtpWebResponse)reqFTP.GetResponse();
  76:             var responseStream = response.GetResponseStream();
  77:             var writeStream = new FileStream(Path.Combine(destinationPath, file), FileMode.Create);
  78:             const int length = 2048;
  79:             var buffer = new Byte[length];
  80:             if (responseStream != null)
  81:             {
  82:                 int bytesRead = responseStream.Read(buffer, 0, length);
  83:                 while (bytesRead > 0)
  84:                 {
  85:                     writeStream.Write(buffer, 0, bytesRead);
  86:                     bytesRead = responseStream.Read(buffer, 0, length);
  87:                 }
  88:             }
  89:             writeStream.Close();
  90:             response.Close();
  91:  
  92:         }
  93:     }

Der Username und das Passwort kann im Azure Website Management Portal gesetzt werden. Dies ist auch der User, der für ein evtl. Git-Deployment berechtigt ist.

Ergebnis:

Die Dateien in dem Ordner werden alle heruntergeladen.

image

Der Code ist natürlich auch auf GitHub zu finden.


Written by Robert Muehsig

Software Developer - from Dresden, Germany, now living & working in Switzerland. Microsoft MVP & Web Geek.
Other Projects: KnowYourStack.com | ExpensiveMeeting | EinKofferVollerReisen.de

If you like the content and want to support me you could buy me a beer or a coffee via Litecoin or Bitcoin - thanks for reading!