示例#1
0
        public static void SetupLogging(LJTraceSource tracer, IShutdown shutdown)
        {
            void unhandledExceptionEventHandler(object sender, UnhandledExceptionEventArgs e)
            {
                string logMsg = "Unhandled domain exception occurred";

                if (e.ExceptionObject is Exception ex)
                {
                    tracer.Error((Exception)e.ExceptionObject, logMsg);
                }
                else
                {
                    tracer.Error("{0}: ({1}) {2}", logMsg, e.ExceptionObject.GetType(), e.ExceptionObject);
                }
            }

            AppDomain.CurrentDomain.UnhandledException += unhandledExceptionEventHandler;

            void unobservedTaskExceptionEventHandler(object sender, UnobservedTaskExceptionEventArgs e)
            {
                tracer.Error(e.Exception, "UnobservedTaskException");
            }

            TaskScheduler.UnobservedTaskException += unobservedTaskExceptionEventHandler;

            shutdown.Phase2Cleanup += (s, e) =>
            {
                AppDomain.CurrentDomain.UnhandledException -= unhandledExceptionEventHandler;
                TaskScheduler.UnobservedTaskException      -= unobservedTaskExceptionEventHandler;
            };
        }
示例#2
0
 void IDisposable.Dispose()
 {
     if (disposed)
     {
         return;
     }
     trace.Info("disposing autoupdater");
     disposed = true;
     if (isActiveAutoUpdaterInstance)
     {
         bool workerCompleted = false;
         changeListenerSubscription.Dispose();
         workerCancellation.Cancel();
         workerCancellationTask.TrySetResult(1);
         try
         {
             trace.Info("waiting autoupdater worker to stop");
             workerCompleted = worker.Wait(TimeSpan.FromSeconds(10));
         }
         catch (AggregateException e)
         {
             trace.Error(e, "autoupdater worker failed");
         }
         trace.Info("autoupdater {0}", workerCompleted ? "stopped" : "did not stop");
         if (workerCompleted)
         {
             workerCancellation.Dispose();
         }
     }
 }
示例#3
0
 async Task <DownloadUpdateResult> IUpdateDownloader.DownloadUpdate(string etag, Stream targetStream, CancellationToken cancellation)
 {
     try
     {
         return(await DownloadUpdateInternal(etag, targetStream, cancellation));
     }
     catch (WebException we)
     {
         trace.Error(we, "failed to download update");
         return(new DownloadUpdateResult()
         {
             Status = DownloadUpdateResult.StatusCode.Failure, ErrorMessage = we.Message
         });
     }
 }
示例#4
0
        public PluginsManager(
            IApplication entryPoint,
            UI.Presenters.MainForm.IPresenter mainFormPresenter,
            Telemetry.ITelemetryCollector telemetry,
            IShutdown shutdown)
        {
            this.tracer            = new LJTraceSource("Extensibility", "plugins-mgr");
            this.entryPoint        = entryPoint;
            this.mainFormPresenter = mainFormPresenter;

            InitPlugins(telemetry);
            RegisterInteropClasses();
            LoadTabExtensions();

            mainFormPresenter.TabChanging += (sender, e) =>
            {
                var ext = e.CustomTabTag as IMainFormTabExtension;
                if (ext == null)
                {
                    return;
                }
                try
                {
                    ext.OnTabPageSelected();
                }
                catch (Exception ex)
                {
                    telemetry.ReportException(ex, "activation of plugin tab: " + ext.Caption);
                    tracer.Error(ex, "Failed to activate extension tab");
                }
            };

            shutdown.Cleanup += (s, e) => Dispose();
        }
示例#5
0
 static void FinalizeInstallation(string installationDir, LJTraceSource trace)
 {
         #if CRAP // The code changes permissions to allow any mac user update app. This approach does not work :(
     // keeping the chmod code until working solution is found.
     trace.Info("finalizing installation");
     var appPath = Path.GetFullPath(Path.Combine(installationDir, appLocationRelativeToInstallationRoot));
     var chmod   = Process.Start("chmod", "g+w \"" + appPath + "\"");
     trace.Error("changing premission for '{0}'", appPath);
     if (chmod == null)
     {
         trace.Error("failed to start chmod");
     }
     else if (!chmod.WaitForExit(5000))
     {
         trace.Error("chmod did not quit");
     }
     else if (chmod.ExitCode != 0)
     {
         trace.Error("chmod did not quit ok: {0}", chmod.ExitCode);
     }
         #endif
 }
示例#6
0
        async Task IWorkspacesManager.SaveWorkspace(string name, string annotation)
        {
            WorkspaceInfo initialWorkspace = currentWorkspace;
            var           entriesStreams   = new List <KeyValuePair <string, Stream> >();

            try
            {
                SetLastError(null);
                SetStatus(WorkspacesManagerStatus.CreatingWorkspace);

                SetCurrentWorkspace(CreateWorkspaceInfo(name, annotation));

                var createdWs = await CreateWorkspace(
                    name, annotation, initialWorkspace != null && initialWorkspace.Name == name, entriesStreams);

                SetCurrentWorkspace(CreateWorkspaceInfoForJustCreatedWs(createdWs, annotation));

                SetStatus(WorkspacesManagerStatus.SavingWorkspaceData);

                await UploadEntriesArchive(createdWs.entriesArchiveUrl, await CreateEntriesArchive(entriesStreams));

                SetStatus(WorkspacesManagerStatus.AttachedToUploadedWorkspace);

                recentlyUsedEntities.RegisterRecentWorkspaceEntry(createdWs.selfUrl, createdWs.id, annotation);
            }
            catch (Exception e)
            {
                tracer.Error(e, "failed to save ws");
                SetLastError(e.Message);
                SetStatus(WorkspacesManagerStatus.FailedToUploadWorkspace);
            }
            finally
            {
                entriesStreams.ForEach(e => e.Value.Dispose());
            }
        }
示例#7
0
        async Task <TelemetryUploadResult> ITelemetryUploader.Upload(
            DateTime recordTimestamp,
            string recordId,
            Dictionary <string, string> fields,
            CancellationToken cancellation
            )
        {
            if (telemetryUrl == null)
            {
                throw new InvalidOperationException("telemetry uploader is not initialized");
            }
            var request = HttpWebRequest.CreateHttp(telemetryUrl);

            request.Method      = "POST";
            request.ContentType = "application/json";
            request.Accept      = "application/json;odata=fullmetadata";
            request.Headers.Add("x-ms-version", "2016-05-31");
            //request.Headers.Add("Prefer", "return-no-content");
            using (var requestStream = await request.GetRequestStreamAsync().WithCancellation(cancellation))
                using (var requestWriter = new StreamWriter(requestStream))
                {
                    JsonSerializer.CreateDefault().Serialize(requestWriter, new Dictionary <string, string>()
                    {
                        { "PartitionKey", recordTimestamp.ToString("s") }, // PK = timestamp in sortable format
                        { "RowKey", recordId },                            // RK = telemetry record ID
                    }.Union(fields).ToDictionary(r => r.Key, r => r.Value));
                }
            using (var response = (HttpWebResponse)await request.GetResponseNoException().WithCancellation(cancellation))
            {
                if (response.StatusCode == HttpStatusCode.NoContent ||
                    response.StatusCode == HttpStatusCode.Created ||
                    response.StatusCode == HttpStatusCode.OK)
                {
                    return(TelemetryUploadResult.Success);
                }
                if (response.StatusCode == HttpStatusCode.Conflict)
                {
                    return(TelemetryUploadResult.Duplicate);
                }
                using (var responseStream = response.GetResponseStream())
                    using (var responseReader = new StreamReader(responseStream))
                    {
                        trace.Error("Failed to upload telemetry: {0}", await responseReader.ReadToEndAsync());
                    }
                return(TelemetryUploadResult.Failure);
            }
        }
示例#8
0
 private void testConnectionButton_Click(object sender, EventArgs e)
 {
     Cursor = Cursors.WaitCursor;
     try
     {
         factory.TestAccount(CreateStorageAccount());
         MessageBox.Show("Your account is OK");
     }
     catch (Exception ex)
     {
         trace.Error(ex, "Storage account test failed");
         MessageBox.Show(string.Format("Failed to connect to storage account:\n{0}", ex.Message), "Testing your account", MessageBoxButtons.OK, MessageBoxIcon.Warning);
     }
     finally
     {
         Cursor = Cursors.Default;
     }
 }
示例#9
0
        public static async Task PcapToPdmp(
            string pcapFile,
            string[] keyFiles,
            string outputFile,
            ITShark tshark,
            CancellationToken cancellation,
            Action <string> reportStatus,
            LJTraceSource trace
            )
        {
            var tsharkArgs = new StringBuilder();

            tsharkArgs.Append($"-r \"{pcapFile}\"");
            tsharkArgs.Append($" -T pdml -2");
            var keyFile = keyFiles.FirstOrDefault();             // todo: support many files

            if (!string.IsNullOrEmpty(keyFile) && File.Exists(keyFile))
            {
                tsharkArgs.Append($" -o \"ssl.desegment_ssl_records: TRUE\" -o \"ssl.desegment_ssl_application_data: TRUE\" -o \"ssl.keylog_file:{keyFile}\"");
            }
            using (var process = tshark.Start(tsharkArgs.ToString()))
                using (var cancellationSub = cancellation.Register(() => process.Kill()))
                    using (var xmlReader = XmlReader.Create(process.StandardOutput))
                        using (var writer = new StreamWriter(outputFile, false, new UTF8Encoding(false)))
                        {
                            var packetsRead = 0;
                            var processTask = process.GetExitCodeAsync(Timeout.InfiniteTimeSpan);
                            using (var statusReportTimer = new Timer(
                                       _ => reportStatus($"converting to text: {packetsRead} packets"), null,
                                       TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(1)))
                            {
                                await Task.WhenAll(
                                    processTask,
                                    Convert(xmlReader, writer, cancellation, val => packetsRead = val, trace)
                                    );
                            }
                            if (processTask.Result != 0)
                            {
                                trace.Error("tshark failed: {0}", process.StandardError.ReadToEnd());
                                throw new Exception($"tshark failed with code {processTask.Result}");
                            }
                        }
        }
示例#10
0
        async Task IPendingUpdate.Dispose()
        {
            trace.Info("Disposing");
            var updaterTask = updaterProcess.GetExitCodeAsync(TimeSpan.FromSeconds(10));

            updaterProcess.Kill();
            await updaterTask;

            if (Directory.Exists(tempInstallationDir))
            {
                trace.Info("Deleting temp update folder");
                try
                {
                    Directory.Delete(tempInstallationDir, true);
                }
                catch (Exception e)
                {
                    trace.Error(e, "Failed to delete temp folder");
                }
            }
            trace.Info("Disposed");
        }
示例#11
0
        public static async Task <IPendingUpdate> Create(
            IFactory factory,
            ITempFilesManager tempFiles,
            ITraceSourceFactory traceSourceFactory,
            MultiInstance.IInstancesCounter mutualExecutionCounter,
            IReadOnlyList <Extensibility.IPluginInfo> requiredPlugins,
            string managedAssembliesPath,
            string updateLogFileName,
            CancellationToken cancellation
            )
        {
            LJTraceSource trace = traceSourceFactory.CreateTraceSource("AutoUpdater", $"pupd-{Interlocked.Increment(ref pendingUpdateIdx)}");

            string installationDir = Path.GetFullPath(
                Path.Combine(managedAssembliesPath, Constants.installationPathRootRelativeToManagedAssembliesLocation));
            string tempInstallationDir = GetTempInstallationDir(installationDir, tempFiles);

            async Task <(string tempZipFile, DownloadUpdateResult result)> Download(IUpdateDownloader updateDownloader, string name)
            {
                var tempFileName = tempFiles.GenerateNewName();

                using (var tempFileStream = new FileStream(tempFileName, FileMode.Create, FileAccess.Write))
                {
                    trace.Info("downloading update for '{0}' to '{1}'", name, tempFileName);
                    var downloadResult = await updateDownloader.DownloadUpdate(null, tempFileStream, cancellation);

                    cancellation.ThrowIfCancellationRequested();
                    if (downloadResult.Status == DownloadUpdateResult.StatusCode.Failure)
                    {
                        throw new Exception($"Failed to download update for {name}: {downloadResult.ErrorMessage}");
                    }
                    return(tempFileName, downloadResult);
                }
            }

            var downloadResults = await Task.WhenAll(
                new[] { Download(factory.CreateAppUpdateDownloader(), "app") }
                .Union(requiredPlugins.Select(plugin => Download(factory.CreatePluginUpdateDownloader(plugin), plugin.Name)))
                );

            void UnzipDownloadedUpdate(string zipFileName, string targetDir)
            {
                using (var fs = new FileStream(zipFileName, FileMode.Open))
                    using (var zipFile = new ZipArchive(fs, ZipArchiveMode.Read))
                    {
                        try
                        {
                            zipFile.ExtractToDirectory(targetDir);
                        }
                        catch (UnauthorizedAccessException e)
                        {
                            throw new BadInstallationDirException(e);
                        }
                    }
                cancellation.ThrowIfCancellationRequested();
            }

            trace.Info("unzipping downloaded update to {0}", tempInstallationDir);
            UnzipDownloadedUpdate(downloadResults[0].tempZipFile, tempInstallationDir);

            var newUpdateInfoPath = Path.Combine(tempInstallationDir,
                                                 Constants.managedAssembliesLocationRelativeToInstallationRoot, Constants.updateInfoFileName);

            new UpdateInfoFileContent(downloadResults[0].result.ETag, DateTime.UtcNow, null).Write(newUpdateInfoPath);

            UpdatePermissions(tempInstallationDir);

            trace.Info("starting updater");

            async Task <(Process process, string autoRestartFlagFileName)> StartUpdater()
            {
                var    tempUpdaterExePath = tempFiles.GenerateNewName() + ".lj.updater.exe";
                string updaterExePath;
                string programToStart;
                string firstArg;
                string autoRestartCommandLine;
                string autoRestartIPCKey;
                string restartFlagFileName;

                if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
                {
                    updaterExePath = Path.Combine(installationDir, Constants.managedAssembliesLocationRelativeToInstallationRoot, "logjoint.updater.exe");
                    var monoPath = @"/Library/Frameworks/Mono.framework/Versions/Current/bin/mono";
                    programToStart         = monoPath;
                    firstArg               = string.Format("\"{0}\" ", tempUpdaterExePath);
                    restartFlagFileName    = tempFiles.GenerateNewName() + ".autorestart";
                    autoRestartIPCKey      = restartFlagFileName;
                    autoRestartCommandLine = Path.GetFullPath(Path.Combine(installationDir, ".."));
                }
                else
                {
                    updaterExePath         = Path.Combine(installationDir, "updater", "logjoint.updater.exe");
                    programToStart         = tempUpdaterExePath;
                    firstArg               = "";
                    autoRestartIPCKey      = Constants.startAfterUpdateEventName;
                    autoRestartCommandLine = Path.Combine(installationDir, "logjoint.exe");
                    restartFlagFileName    = null;
                }

                File.Copy(updaterExePath, tempUpdaterExePath);

                trace.Info("updater executable copied to '{0}'", tempUpdaterExePath);

                trace.Info("this update's log is '{0}'", updateLogFileName);

                var updaterExeProcessParams = new ProcessStartInfo()
                {
                    UseShellExecute = false,
                    FileName        = programToStart,
                    Arguments       = string.Format("{0}\"{1}\" \"{2}\" \"{3}\" \"{4}\" \"{5}\" \"{6}\"",
                                                    firstArg,
                                                    installationDir,
                                                    tempInstallationDir,
                                                    mutualExecutionCounter.MutualExecutionKey,
                                                    updateLogFileName,
                                                    autoRestartIPCKey,
                                                    autoRestartCommandLine
                                                    ),
                    WorkingDirectory = Path.GetDirectoryName(tempUpdaterExePath)
                };

                trace.Info("starting updater executable '{0}' with args '{1}'",
                           updaterExeProcessParams.FileName,
                           updaterExeProcessParams.Arguments);

                Environment.SetEnvironmentVariable("MONO_ENV_OPTIONS", "");                 // todo
                var process = Process.Start(updaterExeProcessParams);

                // wait a bit to catch and log immediate updater's failure
                for (int i = 0; i < 10 && !cancellation.IsCancellationRequested; ++i)
                {
                    if (process.HasExited && process.ExitCode != 0)
                    {
                        trace.Error("updater process exited abnormally with code {0}", process.ExitCode);
                        break;
                    }
                    await Task.Delay(100);
                }
                return(process, restartFlagFileName);
            }

            var(updater, autoRestartFlagFileName) = await StartUpdater();

            var key = factory.CreateUpdateKey(
                downloadResults[0].result.ETag,
                ImmutableDictionary.CreateRange(
                    downloadResults.Skip(1).Select(r => r.result.ETag).Zip(requiredPlugins, (etag, plugin) => new KeyValuePair <string, string>(plugin.Id, etag))
                    )
                );

            var pluginsFolder = Path.Combine(tempInstallationDir, Constants.managedAssembliesLocationRelativeToInstallationRoot, "Plugins");

            if (Directory.Exists(pluginsFolder))
            {
                Directory.Delete(pluginsFolder, true);
            }
            Directory.CreateDirectory(pluginsFolder);


            var pluginFormats = new HashSet <string>();

            foreach (var plugin in downloadResults.Skip(1).Zip(requiredPlugins, (downloadResult, plugin) => (plugin, downloadResult)))
            {
                var pluginFolder = Path.Combine(pluginsFolder, plugin.plugin.Id);
                UnzipDownloadedUpdate(plugin.downloadResult.tempZipFile, pluginFolder);
                new UpdateInfoFileContent(plugin.downloadResult.result.ETag, plugin.downloadResult.result.LastModifiedUtc, null).Write(
                    Path.Combine(pluginFolder, Constants.updateInfoFileName));

                try
                {
                    Extensibility.IPluginManifest manifest = new Extensibility.PluginManifest(pluginFolder);
                    pluginFormats.UnionWith(manifest.Files
                                            .Where(f => f.Type == Extensibility.PluginFileType.FormatDefinition)
                                            .Select(f => Path.GetFileName(f.AbsolulePath).ToLower()));
                }
                catch (Extensibility.BadManifestException)
                {
                    continue;
                }
            }

            CopyCustomFormats(
                managedAssembliesPath,
                Path.Combine(tempInstallationDir, Constants.managedAssembliesLocationRelativeToInstallationRoot),
                pluginFormats,                 // Temporary measure: plugin formats used to be copied to root Formats folder. Ignore them on update.
                trace
                );

            return(new PendingUpdate(tempInstallationDir, key, trace, updater, autoRestartFlagFileName));
        }
示例#12
0
 private void InitPlugins(Telemetry.ITelemetryCollector telemetry)
 {
     using (tracer.NewFrame)
     {
         string thisPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
         tracer.Info("plugins directory: {0}", thisPath);
         foreach (string pluginPath in Directory.GetFiles(thisPath, "*.plugin.dll"))
         {
             tracer.Info("---> plugin found {0}", pluginPath);
             Stopwatch sw = Stopwatch.StartNew();
             Assembly  pluginAsm;
             try
             {
                 pluginAsm = Assembly.LoadFrom(pluginPath);
             }
             catch (Exception e)
             {
                 tracer.Error(e, "failed to load plugin");
                 telemetry.ReportException(e, "loading pluging " + pluginPath);
                 continue;
             }
             var  loadTime   = sw.Elapsed;
             Type pluginType = pluginAsm.GetType("LogJoint.Plugin");
             if (pluginType == null)
             {
                 tracer.Warning("plugin class not found in plugin assembly");
                 continue;
             }
             if (!typeof(PluginBase).IsAssignableFrom(pluginType))
             {
                 tracer.Warning("plugin class doesn't inherit PluginBase");
                 continue;
             }
             sw.Restart();
             PluginBase plugin;
             try
             {
                 plugin = (PluginBase)Activator.CreateInstance(pluginType);
             }
             catch (Exception e)
             {
                 tracer.Error(e, "failed to create an instance of plugin");
                 telemetry.ReportException(e, "creation of plugin " + pluginPath);
                 continue;
             }
             var instantiationTime = sw.Elapsed;
             sw.Restart();
             try
             {
                 plugin.Init(entryPoint);
             }
             catch (Exception e)
             {
                 plugin.Dispose();
                 tracer.Error(e, "failed to init an instance of plugin");
                 telemetry.ReportException(e, "initializtion of plugin " + pluginPath);
                 continue;
             }
             var initTime = sw.Elapsed;
             tracer.Info("plugin {0} accepted. times: loading={1}, instantiation={2}, initialization={3}",
                         Path.GetFileName(pluginPath), loadTime, instantiationTime, initTime);
             plugins.Add(plugin);
         }
     }
 }
示例#13
0
        private static async Task Convert(XmlReader xmlReader, TextWriter writer, CancellationToken cancellation, Action <int> reportPacketsRead, LJTraceSource trace)
        {
            if (!xmlReader.ReadToFollowing("pdml"))
            {
                throw new Exception("bad pdml");
            }

            var maxElementSize   = 1 * 1024 * 512;
            var reductionMethods = new Action <XElement>[]
            {
                (e) => ShortenAttrs(e, "show", 512),
                (e) => ShortenAttrs(e, "value", 512),
                (e) => DeleteProto(e, "json"),
                (e) => ShortenAttrs(e, "show", 64),
                (e) => ShortenAttrs(e, "value", 64),
                (e) => DeleteProto(e, "frame"),
                (e) => DeleteProto(e, "eth"),
                (e) => DeleteProto(e, "data-text-lines")
            };

            int packetsRead = 0;

            Action wrapErrors(Action a, string name) => () =>
            {
                try
                {
                    a();
                }
                catch (Exception e)
                {
                    trace.Error(e, "PDML converter failed in " + name);
                    throw;
                }
            };

            BlockingCollection <XElement> queue = new BlockingCollection <XElement>(1024);

            var producer = Task.Run(wrapErrors(() =>
            {
                try
                {
                    foreach (var packet in ReadChildrenElements(xmlReader))
                    {
                        queue.Add(packet);
                        if (cancellation.IsCancellationRequested)
                        {
                            break;
                        }
                    }
                }
                finally
                {
                    queue.CompleteAdding();
                }
            }, "producer"));

            var consumer = Task.Run(wrapErrors(() =>
            {
                int packetsCompressed = 0;

                writer.WriteLine("<pdml>");
                using (var xmlWriter = XmlWriter.Create(writer, new XmlWriterSettings
                {
                    Indent = true,
                    CloseOutput = false,
                    ConformanceLevel = ConformanceLevel.Fragment,
                    OmitXmlDeclaration = true
                }))
                {
                    foreach (var packet in queue.GetConsumingEnumerable())
                    {
                        cancellation.ThrowIfCancellationRequested();
                        if (packet.Name != "packet")
                        {
                            throw new Exception($"unexpected node in pdml: {packet.Name}");
                        }

                        bool reductionUsed = false;
                        for (int reductionMethodIdx = 0;; ++reductionMethodIdx)
                        {
                            int packetLen = packet.ToString().Length;
                            if (packetLen <= maxElementSize)
                            {
                                break;
                            }
                            if (reductionMethodIdx >= reductionMethods.Length)
                            {
                                throw new Exception($"packet is too large: {GetPacketDisplayName(packet)}");
                            }
                            reductionMethods[reductionMethodIdx](packet);
                            reductionUsed = true;
                        }
                        if (reductionUsed)
                        {
                            ++packetsCompressed;
                        }

                        packet.WriteTo(xmlWriter);

                        ++packetsRead;
                        reportPacketsRead(packetsRead);
                    }
                }
                writer.WriteLine();
                writer.WriteLine();
                writer.WriteLine("</pdml>");

                trace.Info("PCAP conversion finished. Total packets read: {0}, packets compressed: {1}",
                           packetsRead, packetsCompressed);
            }, "consumer"));

            await Task.WhenAll(producer, consumer);
        }