【问题标题】:How can I log something in USQL UDO?如何在 USQL UDO 中记录一些内容?
【发布时间】:2017-10-17 22:35:29
【问题描述】:

我有自定义提取器,我正在尝试从中记录一些消息。

我尝试了Console.WriteLine 之类的明显方法,但找不到输出在哪里。但是,我在adl://<my_DLS>.azuredatalakestore.net/system/jobservice/jobs/Usql/.../<my_job_id>/ 中发现了一些系统日志。

我怎样才能记录一些东西?是否可以在 Data Lake Store 或 Blob 存储帐户的某处指定日志文件?

【问题讨论】:

    标签: azure-data-lake u-sql


    【解决方案1】:

    最近发布的 U-SQL 为 UDO 添加了诊断日志记录。请参阅发行说明here

    // Enable the diagnostics preview feature
    SET @@FeaturePreviews = "DIAGNOSTICS:ON";
    
    
    // Extract as one column
    @input =
        EXTRACT col string
        FROM "/input/input42.txt"
        USING new Utilities.MyExtractor();
    
    
    @output =
        SELECT *
        FROM @input;
    
    
    // Output the file
    OUTPUT @output
    TO "/output/output.txt"
    USING Outputters.Tsv(quoting : false);
    

    这是我来自 UDO 的诊断线:

    Microsoft.Analytics.Diagnostics.DiagnosticStream.WriteLine(System.String.Format("Concatenations done: {0}", i));

    这是整个 UDO:

    using System.Collections.Generic;
    using System.IO;
    using System.Text;
    using Microsoft.Analytics.Interfaces;
    
    namespace Utilities
    {
        [SqlUserDefinedExtractor(AtomicFileProcessing = true)]
        public class MyExtractor : IExtractor
        {
            //Contains the row
            private readonly Encoding _encoding;
            private readonly byte[] _row_delim;
            private readonly char _col_delim;
    
            public MyExtractor()
            {
                _encoding = Encoding.UTF8;
                _row_delim = _encoding.GetBytes("\n\n");
                _col_delim = '|';
            }
    
            public override IEnumerable<IRow> Extract(IUnstructuredReader input, IUpdatableRow output)
            {
                string s = string.Empty;
                string x = string.Empty;
                int i = 0;
    
                foreach (var current in input.Split(_row_delim))
                {
                    using (System.IO.StreamReader streamReader = new StreamReader(current, this._encoding))
                    {
                        while ((s = streamReader.ReadLine()) != null)
                        {
                            //Strip any line feeds
                            //s = s.Replace("/n", "");
    
                            // Concatenate the lines
                            x += s;
                            i += 1;
    
                        }
    
                        Microsoft.Analytics.Diagnostics.DiagnosticStream.WriteLine(System.String.Format("Concatenations done: {0}", i));
    
                        //Create the output
                        output.Set<string>(0, x);
                        yield return output.AsReadOnly();
    
                        // Reset
                        x = string.Empty;
    
                    }
                }
            }
        }
    }
    

    这些是我在以下目录中找到的结果:

    /system/jobservice/jobs/Usql/2017/10/20.../diagnosticstreams

    【讨论】:

    • 谢谢,这正是我想要的!我没有找到更改目标文件的方法,但现在没关系。
    • 您能否提交一个功能请求,说明您可能希望在aka.ms/adlfeedback 更改目标文件的动机?
    • 有没有什么方法可以直接从 USQL 登录而不需要代码隐藏?
    【解决方案2】:

    好问题。我一直在问自己同样的事情。这是理论上的,但我认为它会起作用(如果我发现不同,我会更新)。

    一种非常老套的方法是,您可以将行插入到表中,并将日志消息作为字符串列。然后,您可以根据一些 log_producer_id 列选择它们并过滤。如果部分脚本有效,您还可以获得日志记录的好处,但后面的部分不会假设失败不会回滚。表也​​可以在最后转储到文件中。

    对于错误情况,您可以使用 ADLA 中的作业管理器打开作业图,然后查看作业输出。这些错误通常包含与数据相关的错误的详细信息(例如,有错误的文件中的行号以及带有### 标记的行的八进制/十六进制/ascii 转储)。

    希望这会有所帮助,

    J

    ps。这实际上不是评论或答案,因为我没有工作代码。如果上述想法有误,请提供反馈。

    【讨论】:

    • 谢谢,这应该可行,我们已经考虑过了。但它看起来更像是一些 hack,我更喜欢更自然的解决方案。
    • 完全同意,这很 hacky。我过去曾向 Michael Rys (MSoft ADLA/UDO Guru) 询问过这个问题,但我敢打赌他手头有当前的最佳实践。如果我们能够在没有输出语句的情况下登录到输出文件,那就太好了……例如类似于 daemon/nohup 2>&1 从 ADLA 作业包装器到作业输出中存在的自动生成的 Console.out 文件。
    • 正如 Bob 在他的回答中提到的,我们现在确实拥有 DiagnosticStream 功能。工具团队也在努力在工具中添加对它的支持。
    猜你喜欢
    • 1970-01-01
    • 2015-09-06
    • 2014-12-13
    • 1970-01-01
    • 1970-01-01
    • 2012-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多