Repository: sqlfluff/sqlfluff
Issue: Warnings are not being handled correctly with --format json

-- If this is a parsing or linting issue, please include a minimal SQL example which reproduces the issue, along with the `sqlfluff parse` output, `sqlfluff lint` output and `sqlfluff fix` output when relevant. Finally, please add any labels that are related to the issue before submitting so that it can be addressed easily! --

## Expected Behaviour
warnings should print to stderr and not stdout

## Observed Behaviour
the main takeaway is: “warnings are printing to stdout, not stderr, so readJSON is getting tripped up on that raw report. It’s not actually JSON.”
linking to slack thread: https://sqlfluff.slack.com/archives/C01GX4L213J/p1615395313046700
also just reposting what i asked in slack: 

we run sqlfluff in jenkins to lint on PRs and we have it set to output the results as json, this is the config if it helps:
```
    echo "SQLFluff analyzing"
    container.exec("sqlfluff --version")
    def sqlFiles = "dbt/models"
    def fluffReportRaw = container.captureExec("sqlfluff lint --format json --nofail ${sqlFiles}")
    def fluffReport = readJSON(text: fluffReportRaw)
```
the issue is that the warnings we are getting that i asked about a week-ish ago i.e.
```
WARNING    Indent balance test failed for 'dbt/models/clickstream/mapping_tables/clickstream_returning_sessions.sql'. Template indents will not be linted for this file. 
```
are not getting formatted as json, and are causing this to fail. is there a way to ignore these warnings for the time being? im also not sure if this is a bug since they arent getting formatted as json in the output. quote from one of our devops ppl who was helping me troubleshoot “Looks like those warnings are printing to stdout, not stderr, so readJSON is getting tripped up on that raw report. It’s not actually JSON.”

## Steps to Reproduce

## Version
Include the output of `sqlfluff --version` along with your Python version
sqlfluff 0.4.1
python 3.7.5

## Configuration
```
[sqlfluff]
verbose = 0
nocolor = False
dialect = snowflake
templater = jinja
rules = L010,L012,L023,L030
exclude_rules = None
recurse = 0
output_line_length = 80
ignore = parsing,templating

[sqlfluff:indentation]
indented_joins = False

[sqlfluff:templater:jinja]
apply_dbt_builtins = True
load_macros_from_path=dbt/macros/parsing

[sqlfluff:templater:jinja:macros]
# Macros provided as builtins for dbt projects
dbt_ref = {% macro ref(model_ref) %}{{model_ref}}{% endmacro %}
dbt_source = {% macro source(source_name, table) %}{{source_name}}_{{table}}{% endmacro %}
dbt_config = {% macro config() %}{% for k in kwargs %}{% endfor %}{% endmacro %}
dbt_var = {% macro var(variable) %}item{% endmacro %}

# Some rules can be configured directly from the config common to other rules.
[sqlfluff:rules]
tab_space_size = 2
max_line_length = 80
indent_unit = space
comma_style = trailing
allow_scalar = True
single_table_references = consistent
only_aliases = True

# Some rules have their own specific config

#inconsistent capitalization of keywords
[sqlfluff:rules:L010]
capitalisation_policy = upper

#unquoted identifiers
[sqlfluff:rules:L014]
capitalisation_policy = consistent

#uppercase functions
[sqlfluff:rules:L030]
capitalisation_policy = upper

```


Changed files:
src/sqlfluff/cli/commands.py

diff --git a/src/sqlfluff/cli/commands.py b/src/sqlfluff/cli/commands.py
index b7116e52..14beb1df 100644
--- a/src/sqlfluff/cli/commands.py
+++ b/src/sqlfluff/cli/commands.py
@@ -48,7 +48,7 @@ class RedWarningsFilter(logging.Filter):
         return True
 
 
-def set_logging_level(verbosity, logger=None):
+def set_logging_level(verbosity, logger=None, stderr_output=False):
     """Set up logging for the CLI.
 
     We either set up global logging based on the verbosity
@@ -69,7 +69,7 @@ def set_logging_level(verbosity, logger=None):
     colorama.init()
 
     # Set up the log handler to log to stdout
-    handler = logging.StreamHandler(stream=sys.stdout)
+    handler = logging.StreamHandler(stream=sys.stderr if stderr_output else sys.stdout)
     # NB: the unicode character at the beginning is to squash any badly
     # tamed ANSI colour statements, and return us to normality.
     handler.setFormatter(logging.Formatter("\\u001b[0m%(levelname)-10s %(message)s"))
@@ -306,13 +306,14 @@ def lint(paths, format, nofail, disregard_sqlfluffignores, logger=None, **kwargs
 
     """
     c = get_config(**kwargs)
-    lnt, formatter = get_linter_and_formatter(c, silent=format in ("json", "yaml"))
+    non_human_output = format in ("json", "yaml")
+    lnt, formatter = get_linter_and_formatter(c, silent=non_human_output)
     verbose = c.get("verbose")
 
     formatter.dispatch_config(lnt)
 
     # Set up logging.
-    set_logging_level(verbosity=verbose, logger=logger)
+    set_logging_level(verbosity=verbose, logger=logger, stderr_output=non_human_output)
     # add stdin if specified via lone '-'
     if ("-",) == paths:
         # TODO: Remove verbose
@@ -538,15 +539,16 @@ def parse(path, code_only, format, profiler, bench, nofail, logger=None, **kwarg
     # Initialise the benchmarker
     bencher = BenchIt()  # starts the timer
     c = get_config(**kwargs)
-    # We don't want anything else to be logged if we want a yaml output
-    lnt, formatter = get_linter_and_formatter(c, silent=format in ("json", "yaml"))
+    # We don't want anything else to be logged if we want json or yaml output
+    non_human_output = format in ("json", "yaml")
+    lnt, formatter = get_linter_and_formatter(c, silent=non_human_output)
     verbose = c.get("verbose")
     recurse = c.get("recurse")
 
     formatter.dispatch_config(lnt)
 
     # Set up logging.
-    set_logging_level(verbosity=verbose, logger=logger)
+    set_logging_level(verbosity=verbose, logger=logger, stderr_output=non_human_output)
 
     # TODO: do this better
     nv = 0