示例#1
0
        async Task <string> IWasmFileSystemConfig.ChooseFile()
        {
            var handle = await jsRuntime.InvokeAsync <long>("logjoint.nativeFiles.choose");

            var dbId = await jsRuntime.InvokeAsync <long>("logjoint.nativeFiles.ensureStoredInDatabase", handle);

            var(fileName, fileInfo) = await EnsureNativeFileSystemFileInfoExists(handle, dbId);

            traceSource.Info("chosen file has been given name '{0}' and stored in database with id {1}", fileName, dbId);
            return(fileName);
        }
示例#2
0
        Task INavigationManager.NavigateView(Func <CancellationToken, Task> navigate)
        {
            bool wasInProgress = false;

            if (currentNavigationTask != null)
            {
                wasInProgress = true;
                currentNavigationTaskCancellation.Cancel();
                currentNavigationTask = null;
            }
            var taskId = ++currentNavigationTaskId;

            currentNavigationTaskCancellation = new CancellationTokenSource();
            Func <Task> wrapper = async() =>
            {
                // todo: have perf op for navigation
                tracer.Info("nav begin {0} ", taskId);
                var cancellation = currentNavigationTaskCancellation.Token;
                try
                {
                    await navigate(cancellation);
                }
                catch (OperationCanceledException)
                {
                    throw;                     // fail navigation task with same exception. don't telemetrize it.
                }
                catch (Exception e)
                {
                    telemetry.ReportException(e, "LogViewer navigation");
                    throw;
                }
                finally
                {
                    tracer.Info("nav end {0}{1}", taskId, cancellation.IsCancellationRequested ? " (cancelled)" : "");
                    if (taskId == currentNavigationTaskId && currentNavigationTask != null)
                    {
                        currentNavigationTask = null;
                        changeNotification.Post();
                    }
                }
            };
            var tmp = wrapper();

            if (!tmp.IsCompleted)
            {
                currentNavigationTask = tmp;
            }
            if (wasInProgress != (currentNavigationTask != null))
            {
                changeNotification.Post();
            }
            return(tmp);
        }
示例#3
0
 void SetStatus(WorkspacesManagerStatus status)
 {
     if (this.status == status)
     {
         return;
     }
     tracer.Info("status {0}->{1}", this.status, status);
     this.status = status;
     if (StatusChanged != null)
     {
         StatusChanged(this, EventArgs.Empty);
     }
 }
 public RollingStrategy(LJTraceSource trace, IConnectionParams connectionParams)
 {
     baseFileName = connectionParams[fileNameParam];
     if (string.IsNullOrEmpty(baseFileName))
     {
         throw new ArgumentException("Base file name is not specified in the connection params");
     }
     baseFileNameFirstChar = GetFileNameFirstChar(baseFileName);
     baseDirectory         = Path.GetDirectoryName(baseFileName);
     trace.Info("Base file name first character: {0}", baseFileNameFirstChar);
 }
示例#5
0
        static void CopyCustomFormats(
            string managedAssmebliesLocation,
            string tmpManagedAssmebliesLocation,
            HashSet <string> execludedFormats,
            LJTraceSource trace
            )
        {
            var srcFormatsDir  = Path.Combine(managedAssmebliesLocation, DirectoryFormatsRepository.RelativeFormatsLocation);
            var destFormatsDir = Path.Combine(tmpManagedAssmebliesLocation, DirectoryFormatsRepository.RelativeFormatsLocation);
            var destFormats    = EnumFormatsDefinitions(destFormatsDir).ToLookup(x => x.Key);

            foreach (var srcFmt in EnumFormatsDefinitions(srcFormatsDir).Where(x => !destFormats.Contains(x.Key)))
            {
                if (execludedFormats.Contains(Path.GetFileName(srcFmt.Value).ToLower()))
                {
                    trace.Info("not copying format excluded format {0}", srcFmt.Key);
                    continue;
                }
                trace.Info("copying user-defined format {0} to {1}", srcFmt.Key, destFormatsDir);
                File.Copy(srcFmt.Value, Path.Combine(destFormatsDir, Path.GetFileName(srcFmt.Value)));
            }
        }
示例#6
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");
        }
示例#7
0
        public override void Post(SendOrPostCallback d, object state)
        {
            var ts = Environment.TickCount;

            if (ts - lastPrintoutTs > 1000)
            {
                lastPrintoutTs = ts;
                trace.Info("SynchronizationContext stats: inflight={0} total={1}", counters.inFlight, counters.total);
            }
            Interlocked.Increment(ref counters.inFlight);
            Interlocked.Increment(ref counters.total);
            ThreadPool.QueueUserWorkItem(st =>
            {
                d.Invoke(st);
                Interlocked.Decrement(ref counters.inFlight);
            }, state);
        }
示例#8
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
 }
        public static void WireupDependenciesAndInitMainWindow(MainWindowAdapter mainWindow)
        {
            var tracer = new LJTraceSource("App", "app");

            tracer.Info("starting app");


            using (tracer.NewFrame)
            {
                ILogProviderFactoryRegistry  logProviderFactoryRegistry  = new LogProviderFactoryRegistry();
                IFormatDefinitionsRepository formatDefinitionsRepository = new DirectoryFormatsRepository(null);
                TempFilesManager             tempFilesManager            = new TempFilesManager();
                IUserDefinedFormatsManager   userDefinedFormatsManager   = new UserDefinedFormatsManager(
                    formatDefinitionsRepository, logProviderFactoryRegistry, tempFilesManager);
                new AppInitializer(tracer, userDefinedFormatsManager, logProviderFactoryRegistry, tempFilesManager);
                tracer.Info("app initializer created");

                IInvokeSynchronization invokingSynchronization = new InvokeSynchronization(new NSSynchronizeInvoke());

                UI.HeartBeatTimer          heartBeatTimer = new UI.HeartBeatTimer();
                UI.Presenters.IViewUpdates viewUpdates    = heartBeatTimer;

                IFiltersFactory   filtersFactory   = new FiltersFactory();
                IBookmarksFactory bookmarksFactory = new BookmarksFactory();
                var bookmarks = bookmarksFactory.CreateBookmarks();
                var persistentUserDataFileSystem = Persistence.Implementation.DesktopFileSystemAccess.CreatePersistentUserDataFileSystem();

                IShutdown shutdown = new Shutdown();

                Persistence.Implementation.IStorageManagerImplementation userDataStorage = new Persistence.Implementation.StorageManagerImplementation();
                Persistence.IStorageManager storageManager = new Persistence.PersistentUserDataManager(
                    userDataStorage,
                    shutdown
                    );
                Settings.IGlobalSettingsAccessor globalSettingsAccessor = new Settings.GlobalSettingsAccessor(storageManager);
                userDataStorage.Init(
                    new Persistence.Implementation.RealTimingAndThreading(),
                    persistentUserDataFileSystem,
                    new Persistence.PersistentUserDataManager.ConfigAccess(globalSettingsAccessor)
                    );
                Persistence.IFirstStartDetector firstStartDetector = persistentUserDataFileSystem;
                Persistence.Implementation.IStorageManagerImplementation contentCacheStorage = new Persistence.Implementation.StorageManagerImplementation();
                contentCacheStorage.Init(
                    new Persistence.Implementation.RealTimingAndThreading(),
                    Persistence.Implementation.DesktopFileSystemAccess.CreateCacheFileSystemAccess(),
                    new Persistence.ContentCacheManager.ConfigAccess(globalSettingsAccessor)
                    );
                LogJoint.Properties.WebContentConfig webContentConfig = new Properties.WebContentConfig();
                Persistence.IContentCache            contentCache     = new Persistence.ContentCacheManager(contentCacheStorage);
                Persistence.IWebContentCache         webContentCache  = new Persistence.WebContentCache(
                    contentCache,
                    webContentConfig
                    );
                MultiInstance.IInstancesCounter     instancesCounter           = new MultiInstance.InstancesCounter(shutdown);
                Progress.IProgressAggregatorFactory progressAggregatorsFactory = new Progress.ProgressAggregator.Factory(heartBeatTimer, invokingSynchronization);
                Progress.IProgressAggregator        progressAggregator         = progressAggregatorsFactory.CreateProgressAggregator();

                IAdjustingColorsGenerator colorGenerator = new AdjustingColorsGenerator(
                    new PastelColorsGenerator(),
                    globalSettingsAccessor.Appearance.ColoringBrightness
                    );

                IModelThreads modelThreads = new ModelThreads(colorGenerator);

                ILogSourcesManager logSourcesManager = new LogSourcesManager(
                    heartBeatTimer,
                    invokingSynchronization,
                    modelThreads,
                    tempFilesManager,
                    storageManager,
                    bookmarks,
                    globalSettingsAccessor
                    );

                Telemetry.ITelemetryUploader telemetryUploader = new Telemetry.ConfiguredAzureTelemetryUploader(
                    );

                Telemetry.ITelemetryCollector telemetryCollector = new Telemetry.TelemetryCollector(
                    storageManager,
                    telemetryUploader,
                    invokingSynchronization,
                    instancesCounter,
                    shutdown,
                    logSourcesManager,
                    new MemBufferTraceAccess()
                    );
                tracer.Info("telemetry created");

                new Telemetry.UnhandledExceptionsReporter(telemetryCollector);

                MRU.IRecentlyUsedEntities recentlyUsedLogs = new MRU.RecentlyUsedEntities(
                    storageManager,
                    logProviderFactoryRegistry,
                    telemetryCollector
                    );
                IFormatAutodetect formatAutodetect = new FormatAutodetect(recentlyUsedLogs, logProviderFactoryRegistry, tempFilesManager);

                Workspaces.IWorkspacesManager workspacesManager = new Workspaces.WorkspacesManager(
                    logSourcesManager,
                    logProviderFactoryRegistry,
                    storageManager,
                    new Workspaces.Backend.AzureWorkspacesBackend(),
                    tempFilesManager,
                    recentlyUsedLogs,
                    shutdown
                    );

                AppLaunch.ILaunchUrlParser launchUrlParser = new AppLaunch.LaunchUrlParser();

                Preprocessing.IPreprocessingManagerExtensionsRegistry preprocessingManagerExtensionsRegistry =
                    new Preprocessing.PreprocessingManagerExtentionsRegistry();

                Preprocessing.ICredentialsCache preprocessingCredentialsCache = new PreprocessingCredentialsCache(
                    mainWindow.Window,
                    storageManager.GlobalSettingsEntry,
                    invokingSynchronization
                    );

                WebBrowserDownloader.IDownloader webBrowserDownloader = new UI.Presenters.WebBrowserDownloader.Presenter(
                    new LogJoint.UI.WebBrowserDownloaderWindowController(),
                    invokingSynchronization,
                    webContentCache,
                    shutdown
                    );

                Preprocessing.IPreprocessingStepsFactory preprocessingStepsFactory = new Preprocessing.PreprocessingStepsFactory(
                    workspacesManager,
                    launchUrlParser,
                    invokingSynchronization,
                    preprocessingManagerExtensionsRegistry,
                    progressAggregator,
                    webContentCache,
                    preprocessingCredentialsCache,
                    logProviderFactoryRegistry,
                    webBrowserDownloader,
                    webContentConfig
                    );

                Preprocessing.ILogSourcesPreprocessingManager logSourcesPreprocessings = new Preprocessing.LogSourcesPreprocessingManager(
                    invokingSynchronization,
                    formatAutodetect,
                    preprocessingManagerExtensionsRegistry,
                    new Preprocessing.BuiltinStepsExtension(preprocessingStepsFactory),
                    telemetryCollector,
                    tempFilesManager
                    );

                ILogSourcesController logSourcesController = new LogSourcesController(
                    logSourcesManager,
                    logSourcesPreprocessings,
                    recentlyUsedLogs,
                    shutdown
                    );

                ISearchManager searchManager = new SearchManager(
                    logSourcesManager,
                    progressAggregatorsFactory,
                    invokingSynchronization,
                    globalSettingsAccessor,
                    telemetryCollector,
                    heartBeatTimer
                    );

                IUserDefinedSearches userDefinedSearchesManager = new UserDefinedSearchesManager(
                    storageManager,
                    filtersFactory,
                    invokingSynchronization
                    );

                ISearchHistory searchHistory = new SearchHistory(
                    storageManager.GlobalSettingsEntry,
                    userDefinedSearchesManager
                    );

                IBookmarksController bookmarksController = new BookmarkController(
                    bookmarks,
                    modelThreads,
                    heartBeatTimer
                    );

                IFiltersManager filtersManager = new FiltersManager(
                    filtersFactory,
                    globalSettingsAccessor,
                    logSourcesManager,
                    colorGenerator,
                    shutdown
                    );

                LogJoint.Postprocessing.IUserNamesProvider analyticsShortNames = new LogJoint.Postprocessing.CodenameUserNamesProvider(
                    logSourcesManager
                    );

                Analytics.TimeSeries.ITimeSeriesTypesAccess timeSeriesTypesAccess = new Analytics.TimeSeries.TimeSeriesTypesLoader();

                LogJoint.Postprocessing.IPostprocessorsManager postprocessorsManager = new LogJoint.Postprocessing.PostprocessorsManager(
                    logSourcesManager,
                    telemetryCollector,
                    invokingSynchronization,
                    heartBeatTimer,
                    progressAggregator,
                    null,                     // todo
                    globalSettingsAccessor
                    );

                LogJoint.Postprocessing.InternalTracePostprocessors.Register(
                    postprocessorsManager,
                    userDefinedFormatsManager
                    );

                tracer.Info("model creation finished");

                AutoUpdate.IAutoUpdater autoUpdater = new AutoUpdate.AutoUpdater(
                    instancesCounter,
                    new AutoUpdate.ConfiguredAzureUpdateDownloader(),
                    tempFilesManager,
                    shutdown,
                    invokingSynchronization,
                    firstStartDetector,
                    telemetryCollector,
                    storageManager
                    );

                var presentersFacade = new UI.Presenters.Facade();
                UI.Presenters.IPresentersFacade navHandler = presentersFacade;

                UI.Presenters.IClipboardAccess clipboardAccess = new UI.ClipboardAccess();
                UI.Presenters.IAlertPopup      alerts          = new UI.AlertPopup();
                UI.Presenters.IShellOpen       shellOpen       = new UI.ShellOpen();
                UI.Presenters.IFileDialogs     fileDialogs     = new UI.FileDialogs();

                UI.Presenters.LogViewer.IPresenterFactory logViewerPresenterFactory = new UI.Presenters.LogViewer.PresenterFactory(
                    heartBeatTimer,
                    presentersFacade,
                    clipboardAccess,
                    bookmarksFactory,
                    telemetryCollector,
                    logSourcesManager,
                    invokingSynchronization,
                    modelThreads,
                    filtersManager.HighlightFilters,
                    bookmarks,
                    globalSettingsAccessor,
                    searchManager,
                    filtersFactory
                    );

                UI.Presenters.LoadedMessages.IView      loadedMessagesView      = mainWindow.LoadedMessagesControlAdapter;
                UI.Presenters.LoadedMessages.IPresenter loadedMessagesPresenter = new UI.Presenters.LoadedMessages.Presenter(
                    logSourcesManager,
                    bookmarks,
                    loadedMessagesView,
                    heartBeatTimer,
                    logViewerPresenterFactory);

                UI.Presenters.LogViewer.IPresenter viewerPresenter = loadedMessagesPresenter.LogViewerPresenter;

                UI.Presenters.StatusReports.IPresenter statusReportPresenter = new UI.Presenters.StatusReports.Presenter(
                    mainWindow.StatusPopupControlAdapter,
                    heartBeatTimer
                    );

                UI.Presenters.SourcePropertiesWindow.IPresenter sourcePropertiesWindowPresenter = new UI.Presenters.SourcePropertiesWindow.Presenter(
                    new UI.SourcePropertiesDialogView(),
                    logSourcesManager,
                    logSourcesPreprocessings,
                    navHandler,
                    alerts,
                    clipboardAccess,
                    shellOpen
                    );

                UI.Presenters.SaveJointLogInteractionPresenter.IPresenter saveJointLogInteractionPresenter = new UI.Presenters.SaveJointLogInteractionPresenter.Presenter(
                    logSourcesManager,
                    shutdown,
                    progressAggregatorsFactory,
                    alerts,
                    fileDialogs,
                    statusReportPresenter
                    );

                UI.Presenters.SourcesList.IPresenter sourcesListPresenter = new UI.Presenters.SourcesList.Presenter(
                    logSourcesManager,
                    mainWindow.SourcesManagementControlAdapter.SourcesListControlAdapter,
                    logSourcesPreprocessings,
                    sourcePropertiesWindowPresenter,
                    viewerPresenter,
                    navHandler,
                    alerts,
                    fileDialogs,
                    clipboardAccess,
                    shellOpen,
                    saveJointLogInteractionPresenter
                    );

                UI.Presenters.SearchResult.IPresenter searchResultPresenter = new UI.Presenters.SearchResult.Presenter(
                    searchManager,
                    bookmarks,
                    filtersManager.HighlightFilters,
                    mainWindow.SearchResultsControlAdapter,
                    navHandler,
                    loadedMessagesPresenter,
                    heartBeatTimer,
                    invokingSynchronization,
                    statusReportPresenter,
                    logViewerPresenterFactory
                    );

                UI.Presenters.SearchEditorDialog.IPresenter searchEditorDialog = new UI.Presenters.SearchEditorDialog.Presenter(
                    new SearchEditorDialogView(),
                    userDefinedSearchesManager,
                    (filtersList, dialogView) =>
                {
                    UI.Presenters.FilterDialog.IPresenter filterDialogPresenter = new UI.Presenters.FilterDialog.Presenter(
                        null,                                 // logSources is not required. Scope is not supported by search.
                        filtersList,
                        new UI.FilterDialogController((AppKit.NSWindowController)dialogView)
                        );
                    return(new UI.Presenters.FiltersManager.Presenter(
                               filtersList,
                               dialogView.FiltersManagerView,
                               new UI.Presenters.FiltersListBox.Presenter(
                                   filtersList,
                                   dialogView.FiltersManagerView.FiltersListView,
                                   filterDialogPresenter
                                   ),
                               filterDialogPresenter,
                               null,                          // log viewer is not required
                               viewUpdates,                   // todo: updates must be faked for search editor
                               heartBeatTimer,
                               filtersFactory,
                               alerts
                               ));
                },
                    alerts
                    );



                UI.Presenters.SearchesManagerDialog.IPresenter searchesManagerDialogPresenter = new UI.Presenters.SearchesManagerDialog.Presenter(
                    new UI.SearchesManagerDialogView(),
                    userDefinedSearchesManager,
                    alerts,
                    fileDialogs,
                    searchEditorDialog
                    );

                UI.Presenters.SearchPanel.IPresenter searchPanelPresenter = new UI.Presenters.SearchPanel.Presenter(
                    mainWindow.SearchPanelControlAdapter,
                    searchManager,
                    searchHistory,
                    userDefinedSearchesManager,
                    logSourcesManager,
                    filtersFactory,
                    mainWindow,
                    loadedMessagesPresenter,
                    searchResultPresenter,
                    statusReportPresenter,
                    searchEditorDialog,
                    searchesManagerDialogPresenter,
                    alerts
                    );
                tracer.Info("search panel presenter created");

                UI.Presenters.HistoryDialog.IView      historyDialogView      = new UI.HistoryDialogAdapter();
                UI.Presenters.HistoryDialog.IPresenter historyDialogPresenter = new UI.Presenters.HistoryDialog.Presenter(
                    logSourcesController,
                    historyDialogView,
                    logSourcesPreprocessings,
                    preprocessingStepsFactory,
                    recentlyUsedLogs,
                    new UI.Presenters.QuickSearchTextBox.Presenter(historyDialogView.QuickSearchTextBox),
                    alerts
                    );

                AppLaunch.ICommandLineHandler commandLineHandler = new AppLaunch.CommandLineHandler(
                    logSourcesPreprocessings,
                    preprocessingStepsFactory
                    );

                UI.Presenters.NewLogSourceDialog.IPagePresentersRegistry newLogSourceDialogPagesPresentersRegistry =
                    new UI.Presenters.NewLogSourceDialog.PagePresentersRegistry();

                UI.Presenters.Help.IPresenter helpPresenter = new UI.Presenters.Help.Presenter(
                    shellOpen
                    );

                UI.Presenters.NewLogSourceDialog.IPresenter newLogSourceDialogPresenter = new UI.Presenters.NewLogSourceDialog.Presenter(
                    logProviderFactoryRegistry,
                    newLogSourceDialogPagesPresentersRegistry,
                    recentlyUsedLogs,
                    new UI.NewLogSourceDialogView(),
                    userDefinedFormatsManager,
                    () => new UI.Presenters.NewLogSourceDialog.Pages.FormatDetection.Presenter(
                        new LogJoint.UI.FormatDetectionPageController(),
                        logSourcesPreprocessings,
                        preprocessingStepsFactory
                        ),
                    new UI.Presenters.FormatsWizard.Presenter(
                        new UI.Presenters.FormatsWizard.ObjectsFactory(
                            alerts,
                            fileDialogs,
                            helpPresenter,
                            logProviderFactoryRegistry,
                            formatDefinitionsRepository,
                            userDefinedFormatsManager,
                            tempFilesManager,
                            logViewerPresenterFactory,
                            new UI.Presenters.FormatsWizard.ObjectsFactory.ViewFactories()
                {
                    CreateFormatsWizardView           = () => new FormatsWizardDialogController(),
                    CreateChooseOperationPageView     = () => new ChooseOperationPageController(),
                    CreateImportLog4NetPagePageView   = () => new ImportLog4NetPageController(),
                    CreateFormatIdentityPageView      = () => new FormatIdentityPageController(),
                    CreateFormatAdditionalOptionsPage = () => new FormatAdditionalOptionsPageController(),
                    CreateSaveFormatPageView          = () => new SaveFormatPageController(),
                    CreateImportNLogPage               = () => new ImportNLogPageController(),
                    CreateNLogGenerationLogPageView    = () => new NLogGenerationLogPageController(),
                    CreateChooseExistingFormatPageView = () => new ChooseExistingFormatPageController(),
                    CreateFormatDeleteConfirmPageView  = () => new FormatDeletionConfirmationPageController(),
                    CreateRegexBasedFormatPageView     = () => new RegexBasedFormatPageController(),
                    CreateEditSampleDialogView         = () => new EditSampleLogDialogController(),
                    CreateTestDialogView               = () => new TestFormatDialogController(),
                    CreateEditRegexDialog              = () => new EditRegexDialogController(),
                    CreateEditFieldsMappingDialog      = () => new FieldsMappingDialogController(),
                    CreateXmlBasedFormatPageView       = () => new XmlBasedFormatPageController(),
                    CreateJsonBasedFormatPageView      = () => new XmlBasedFormatPageController(),
                    CreateXsltEditorDialog             = () => new XsltEditorDialogController(),
                    CreateJUSTEditorDialog             = () => new XsltEditorDialogController()
                }
                            )
                        )
                    );

                newLogSourceDialogPagesPresentersRegistry.RegisterPagePresenterFactory(
                    StdProviderFactoryUIs.FileBasedProviderUIKey,
                    f => new UI.Presenters.NewLogSourceDialog.Pages.FileBasedFormat.Presenter(
                        new LogJoint.UI.FileBasedFormatPageController(),
                        (IFileBasedLogProviderFactory)f,
                        logSourcesController,
                        alerts,
                        fileDialogs
                        )
                    );

                UI.Presenters.SharingDialog.IPresenter sharingDialogPresenter = new UI.Presenters.SharingDialog.Presenter(
                    logSourcesManager,
                    workspacesManager,
                    logSourcesPreprocessings,
                    alerts,
                    clipboardAccess,
                    new UI.SharingDialogController()
                    );

                UI.Presenters.SourcesManager.IPresenter sourcesManagerPresenter = new UI.Presenters.SourcesManager.Presenter(
                    logSourcesManager,
                    userDefinedFormatsManager,
                    recentlyUsedLogs,
                    logSourcesPreprocessings,
                    logSourcesController,
                    mainWindow.SourcesManagementControlAdapter,
                    preprocessingStepsFactory,
                    workspacesManager,
                    sourcesListPresenter,
                    newLogSourceDialogPresenter,
                    heartBeatTimer,
                    sharingDialogPresenter,
                    historyDialogPresenter,
                    presentersFacade,
                    sourcePropertiesWindowPresenter,
                    alerts
                    );

                UI.Presenters.BookmarksList.IPresenter bookmarksListPresenter = new UI.Presenters.BookmarksList.Presenter(
                    bookmarks,
                    logSourcesManager,
                    mainWindow.BookmarksManagementControlAdapter.ListView,
                    heartBeatTimer,
                    loadedMessagesPresenter,
                    clipboardAccess
                    );

                UI.Presenters.BookmarksManager.IPresenter bookmarksManagerPresenter = new UI.Presenters.BookmarksManager.Presenter(
                    bookmarks,
                    mainWindow.BookmarksManagementControlAdapter,
                    viewerPresenter,
                    searchResultPresenter,
                    bookmarksListPresenter,
                    statusReportPresenter,
                    navHandler,
                    viewUpdates,
                    alerts
                    );

                UI.Presenters.FilterDialog.IPresenter hlFilterDialogPresenter = new UI.Presenters.FilterDialog.Presenter(
                    logSourcesManager,
                    filtersManager.HighlightFilters,
                    new UI.FilterDialogController(mainWindow)
                    );

                UI.Presenters.FiltersListBox.IPresenter hlFiltersListPresenter = new UI.Presenters.FiltersListBox.Presenter(
                    filtersManager.HighlightFilters,
                    mainWindow.HighlightingFiltersManagerControlAdapter.FiltersList,
                    hlFilterDialogPresenter
                    );

                UI.Presenters.FiltersManager.IPresenter hlFiltersManagerPresenter = new UI.Presenters.FiltersManager.Presenter(
                    filtersManager.HighlightFilters,
                    mainWindow.HighlightingFiltersManagerControlAdapter,
                    hlFiltersListPresenter,
                    hlFilterDialogPresenter,
                    loadedMessagesPresenter.LogViewerPresenter,
                    viewUpdates,
                    heartBeatTimer,
                    filtersFactory,
                    alerts
                    );


                UI.Presenters.MainForm.IDragDropHandler dragDropHandler = new UI.DragDropHandler(
                    logSourcesPreprocessings,
                    preprocessingStepsFactory,
                    logSourcesController
                    );

                new UI.LogsPreprocessorUI(
                    logSourcesPreprocessings,
                    statusReportPresenter
                    );

                UI.Presenters.About.IPresenter aboutDialogPresenter = new UI.Presenters.About.Presenter(
                    new UI.AboutDialogAdapter(),
                    new UI.AboutDialogConfig(),
                    clipboardAccess,
                    autoUpdater
                    );

                UI.Presenters.Timeline.IPresenter timelinePresenter = new UI.Presenters.Timeline.Presenter(
                    logSourcesManager,
                    logSourcesPreprocessings,
                    searchManager,
                    bookmarks,
                    mainWindow.TimelinePanelControlAdapter.TimelineControlAdapter,
                    viewerPresenter,
                    statusReportPresenter,
                    null,                     // tabUsageTracker
                    heartBeatTimer
                    );

                var timeLinePanelPresenter = new UI.Presenters.TimelinePanel.Presenter(
                    mainWindow.TimelinePanelControlAdapter,
                    timelinePresenter
                    );

                UI.Presenters.TimestampAnomalyNotification.IPresenter timestampAnomalyNotification = new UI.Presenters.TimestampAnomalyNotification.Presenter(
                    logSourcesManager,
                    logSourcesPreprocessings,
                    invokingSynchronization,
                    heartBeatTimer,
                    presentersFacade,
                    statusReportPresenter
                    );
                timestampAnomalyNotification.GetHashCode();                 // to suppress warning

                UI.Presenters.IPromptDialog promptDialog = new LogJoint.UI.PromptDialogController();

                UI.Presenters.IssueReportDialogPresenter.IPresenter issueReportDialogPresenter =
                    new UI.Presenters.IssueReportDialogPresenter.Presenter(
                        telemetryCollector, telemetryUploader, promptDialog);

                UI.Presenters.MainForm.IPresenter mainFormPresenter = new UI.Presenters.MainForm.Presenter(
                    logSourcesManager,
                    logSourcesPreprocessings,
                    mainWindow,
                    viewerPresenter,
                    searchResultPresenter,
                    searchPanelPresenter,
                    sourcesListPresenter,
                    sourcesManagerPresenter,
                    null,                    //messagePropertiesDialogPresenter,
                    loadedMessagesPresenter,
                    bookmarksManagerPresenter,
                    heartBeatTimer,
                    null,                    //tabUsageTracker,
                    statusReportPresenter,
                    dragDropHandler,
                    navHandler,
                    autoUpdater,
                    progressAggregator,
                    alerts,
                    sharingDialogPresenter,
                    issueReportDialogPresenter,
                    shutdown
                    );
                tracer.Info("main form presenter created");

                CustomURLSchemaEventsHandler.Instance.Init(
                    mainFormPresenter,
                    commandLineHandler,
                    invokingSynchronization
                    );

                presentersFacade.Init(
                    null,                     //messagePropertiesDialogPresenter,
                    null,                     //threadsListPresenter,
                    sourcesListPresenter,
                    bookmarksManagerPresenter,
                    mainFormPresenter,
                    aboutDialogPresenter,
                    null,                     //optionsDialogPresenter,
                    historyDialogPresenter
                    );

                var postprocessingViewsFactory = new LogJoint.UI.Postprocessing.PostprocessorOutputFormFactory();

                LogJoint.UI.Presenters.Postprocessing.MainWindowTabPage.IView postprocessingTabPage = new LogJoint.UI.Postprocessing.MainWindowTabPage.MainWindowTabPageAdapter(
                    mainFormPresenter
                    );

                LogJoint.UI.Presenters.Postprocessing.MainWindowTabPage.IPresenter postprocessingTabPagePresenter = new LogJoint.UI.Presenters.Postprocessing.MainWindowTabPage.PluginTabPagePresenter(
                    postprocessingTabPage,
                    postprocessorsManager,
                    postprocessingViewsFactory,
                    logSourcesManager,
                    tempFilesManager,
                    shellOpen,
                    newLogSourceDialogPresenter,
                    telemetryCollector
                    );

                LogJoint.Postprocessing.IAggregatingLogSourceNamesProvider logSourceNamesProvider = new LogJoint.Postprocessing.AggregatingLogSourceNamesProvider();

                var extensibilityEntryPoint = new Extensibility.Application(
                    new Extensibility.Model(
                        invokingSynchronization,
                        telemetryCollector,
                        webContentCache,
                        contentCache,
                        storageManager,
                        bookmarks,
                        logSourcesManager,
                        modelThreads,
                        tempFilesManager,
                        preprocessingManagerExtensionsRegistry,
                        logSourcesPreprocessings,
                        preprocessingStepsFactory,
                        progressAggregator,
                        logProviderFactoryRegistry,
                        userDefinedFormatsManager,
                        recentlyUsedLogs,
                        progressAggregatorsFactory,
                        heartBeatTimer,
                        logSourcesController,
                        shutdown,
                        webBrowserDownloader,
                        commandLineHandler,
                        postprocessorsManager,
                        analyticsShortNames,
                        timeSeriesTypesAccess,
                        logSourceNamesProvider
                        ),
                    new Extensibility.Presentation(
                        loadedMessagesPresenter,
                        clipboardAccess,
                        presentersFacade,
                        sourcesManagerPresenter,
                        newLogSourceDialogPresenter,
                        shellOpen,
                        alerts,
                        promptDialog,
                        mainFormPresenter,
                        postprocessingTabPagePresenter,
                        postprocessingViewsFactory
                        ),
                    new Extensibility.View(
                        )
                    );

                postprocessingViewsFactory.Init(extensibilityEntryPoint);

                new Extensibility.PluginsManager(
                    extensibilityEntryPoint,
                    mainFormPresenter,
                    telemetryCollector,
                    shutdown
                    );
            }
        }
示例#10
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));
        }
示例#11
0
        public AutoUpdater(
            IFactory factory,
            MultiInstance.IInstancesCounter mutualExecutionCounter,
            IShutdown shutdown,
            ISynchronizationContext eventInvoker,
            Telemetry.ITelemetryCollector telemetry,
            Persistence.IStorageManager storage,
            ITraceSourceFactory traceSourceFactory,
            Extensibility.IPluginsManagerInternal pluginsManager,
            IChangeNotification changeNotification
            )
        {
            this.updateDownloader = factory.CreateAppUpdateDownloader();
            this.checkRequested   = new TaskCompletionSource <int>();
            this.factory          = factory;
            this.pluginsManager   = pluginsManager;
            this.trace            = traceSourceFactory.CreateTraceSource("AutoUpdater");

            var entryAssemblyLocation = Assembly.GetEntryAssembly()?.Location;

            if (entryAssemblyLocation != null)
            {
                this.managedAssembliesPath = Path.GetDirectoryName(entryAssemblyLocation);
                this.updateInfoFilePath    = Path.Combine(managedAssembliesPath, Constants.updateInfoFileName);
                this.installationDir       = Path.GetFullPath(
                    Path.Combine(managedAssembliesPath, Constants.installationPathRootRelativeToManagedAssembliesLocation));
            }

            this.eventInvoker = eventInvoker;
            this.telemetry    = telemetry;
            this.storage      = storage;

            shutdown.Cleanup += (s, e) => ((IDisposable)this).Dispose();

            this.updatesStorageEntry = storage.GetEntry("updates");

            bool isFirstInstance        = mutualExecutionCounter.IsPrimaryInstance;
            bool isDownloaderConfigured = updateDownloader.IsDownloaderConfigured;

            if (entryAssemblyLocation == null)
            {
                trace.Info("autoupdater is disabled - no entry assembly");
                isActiveAutoUpdaterInstance = false;

                state = AutoUpdateState.Disabled;
            }
            else if (!isDownloaderConfigured)
            {
                trace.Info("autoupdater is disabled - update downloader not configured");
                isActiveAutoUpdaterInstance = false;

                state = AutoUpdateState.Disabled;
            }
            else if (!isFirstInstance)
            {
                trace.Info("autoupdater is deactivated - not a first instance of logjoint");
                isActiveAutoUpdaterInstance = false;

                state = AutoUpdateState.Inactive;
            }
            else
            {
                trace.Info("autoupdater is enabled");
                isActiveAutoUpdaterInstance = true;

                state = AutoUpdateState.Idle;

                workerCancellation      = new CancellationTokenSource();
                workerCancellationToken = workerCancellation.Token;
                workerCancellationTask  = new TaskCompletionSource <int>();

                changeListenerSubscription = changeNotification.CreateSubscription(Updaters.Create(
                                                                                       () => pluginsManager.InstallationRequests,
                                                                                       (_, prev) =>
                {
                    if (prev != null)
                    {
                        checkRequested.TrySetResult(1);
                    }
                }
                                                                                       ));

                worker = TaskUtils.StartInThreadPoolTaskScheduler(Worker);
            }
        }
示例#12
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();
         }
     }
 }
示例#13
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);
         }
     }
 }
示例#14
0
 public static void LogUserAction(this LJTraceSource trace, string action)
 {
     trace.Info("user action: {0}", action);
 }
示例#15
0
 void LogPoint(string pointType, string data)
 {
     trace.Info(data == null ? "perfop #{0} '{1}' {2}" : "perfop #{0} '{1}' {2} '{3}'", id, name, pointType, data);
 }
示例#16
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);
        }