diff --git a/slingshot/cli.py b/slingshot/cli.py
index 55efcf6..047d98e 100644
--- a/slingshot/cli.py
+++ b/slingshot/cli.py
@@ -1,5 +1,6 @@
 # -*- coding: utf-8 -*-
 from __future__ import absolute_import
+from datetime import datetime
 import os
 import shutil
 
@@ -58,4 +59,8 @@ def run(layers, store, url, namespace, username, password):
                 submit(zf, url, auth)
         except Exception as e:
             shutil.rmtree(bag, ignore_errors=True)
+            click.echo("%sZ: %s failed with %r" %
+                       (datetime.utcnow().isoformat(), data_layer, e))
             raise e
+        click.echo("%sZ: %s uploaded" % (datetime.utcnow().isoformat(),
+                                         data_layer))

Add logging
diff --git a/tests/test_cli.py b/tests/test_cli.py
index 1aff724..61eca94 100644
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -59,3 +59,21 @@ def test_run_uses_authentication(runner, layers_dir):
                              '--username', 'foo', '--password', 'bar'])
     assert m.request_history[0].headers['Authorization'] == \
         'Basic Zm9vOmJhcg=='
+
+
+def test_run_logs_uploaded_layers_to_stdout(runner, layers_dir):
+    with requests_mock.Mocker() as m:
+        store = tempfile.mkdtemp()
+        m.post('http://localhost')
+        res = runner.invoke(main, ['run', layers_dir, store,
+                                   'http://localhost'])
+        assert 'SDE_DATA_BD_A8GNS_2003.zip uploaded' in res.output
+
+
+def test_run_logs_failed_layers_to_stdout(runner, layers_dir):
+    with requests_mock.Mocker() as m:
+        store = tempfile.mkdtemp()
+        m.post('http://localhost', status_code=500)
+        res = runner.invoke(main, ['run', layers_dir, store,
+                                   'http://localhost'])
+        assert 'SDE_DATA_BD_A8GNS_2003.zip failed' in res.output

pip install -e .
parse_log_pytest
requirements.txt
pytest mock requests_mock
apt-get update apt-get install -y gcc
3.9
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
bagit==1.5.4
certifi==2025.1.31
charset-normalizer==3.4.1
click==6.3
exceptiongroup==1.2.2
idna==3.10
iniconfig==2.1.0
mock==5.2.0
packaging==24.2
pluggy==1.5.0
pytest==8.3.5
requests==2.32.3
requests-mock==1.12.1
-e git+https://github.com/MITLibraries/slingshot.git@755a842371e63a1c70fde8568523b9b5db0d304e#egg=slingshot
tomli==2.2.1
urllib3==2.3.0

name: slingshot
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - bagit==1.5.4
      - certifi==2025.1.31
      - charset-normalizer==3.4.1
      - click==6.3
      - exceptiongroup==1.2.2
      - idna==3.10
      - iniconfig==2.1.0
      - mock==5.2.0
      - packaging==24.2
      - pluggy==1.5.0
      - pytest==8.3.5
      - requests==2.32.3
      - requests-mock==1.12.1
      - tomli==2.2.1
      - urllib3==2.3.0
      - wheel==0.26.0
prefix: /opt/conda/envs/slingshot

tests/test_cli.py::test_run_logs_uploaded_layers_to_stdout tests/test_cli.py::test_run_logs_failed_layers_to_stdout
tests/test_cli.py::test_run_submits_bags tests/test_cli.py::test_run_leaves_bag_on_success tests/test_cli.py::test_run_removes_bag_on_failure tests/test_cli.py::test_run_uses_supplied_namespace tests/test_cli.py::test_run_uses_authentication
slingshot/cli.py
slingshot/cli.py